编程之美 3.2 电话号码对应单词

主要思路就是递归遍历所有可能的单词;

设置一个数字对应字符集的对照表vec,并设置一个数组count保存每个数字的字符集大小(为了避免在递归中使用str.length()所带来的性能开销);

数组number保存输入的数字;

设置一个flag数组,可以保存当前每一个数字所对应的字母下标;

index记录当前处理到的数字在数组中的下标;

n为输入号码长度;

内存开销基本只有递归的开销比较大;(书上的循环解法真心没看懂,可是作者竟然说循环比递归简单,我了个擦。mark下)

#include<iostream>
#include<string>
#include<vector>
using namespace std;

vector<string> vec;
vector<int> count;

void init(){
    vec.push_back("");
    vec.push_back("");
    vec.push_back("abc");
    vec.push_back("def");
    vec.push_back("ghi");
    vec.push_back("jkl");
    vec.push_back("mno");
    vec.push_back("pqrs");
    vec.push_back("tuv");
    vec.push_back("wxyz");
    for(vector<string>::iterator iter = vec.begin(); iter < vec.end(); ++iter)
        count.push_back((*iter).length());
}

void traversal(const vector<int> &number, vector<int> &flag, int index, int n){
    if (index == n)
    {
        for (int i = 0; i < n; i++){
            if (flag[i] != -1)
                cout << vec[number[i]][flag[i]];
        }
        cout << endl;
        return ;
    }

    if (count[number[index]] == 0){    //如果为0,直接设置该位状态为-1,进入下一行
        flag[index] = -1;
        traversal(number, flag, index + 1, n);
    }
    else 
        for(int j = 0; j < count[number[index]] ; j++)
        {
            flag[index] = j;
            //cout << "index:" << index << "flag[index]:" << flag[index] <<endl;
            traversal(number, flag, index + 1, n);
        }    
}

int main(){
    int n = 0, x = 0;
    vector<int> number;
    vector<int> flag;
    cin >> n;
    for (int i = 0; i < n; i++){
        cin >> x;
        number.push_back(x);
        flag.push_back(0);
    }
    init();
    traversal(number, flag, 0, n);
    return 1;        
}

posted on 2012-12-19 22:50  小龙人2012  阅读(223)  评论(0编辑  收藏  举报

导航