编程之美 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; }