编程之美 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;
}
浙公网安备 33010602011771号