《编程之美》 - 3.2 电话号码对应英文单词 (发现书上递归解法的错误)
/* 题目(改动): 电话的号码潘一般可以用于输入字母。如用 2 可以输入A、B、C,用 3 可以输入 D 、E、F等。 是否可以根据这样的对应关系设计一个程序,输出 所输入数字对应的所有字母的组合 */
/* 代码如下 : */ #include <iostream> #include <string> using namespace std; void NumToWord(string str); int main() { string str; cout << "输入数字:"; cin >>str; NumToWord(str); return 0; } void NumToWord(string str) { //准备工作 char c[10][10] = { "", // 0 "", // 1 "ABC", // 2 "DEF", // 3 "GHI", // 4 "JKL", // 5 "MNO", // 6 "PQRS", // 7 "TUV", // 8 "WXYZ" // 9 }; //每个数字对应有几个英文字母 char total[10] = {0,0,3,3,3,3,3,4,3,4}; // 数组长度 int length = str.length(); // number[i] 为输入的数字的数组 // answer[i] 为 number[i] 所对应的数字所对应的第几个英文字母,初始化为第0个 int number[100]; int answer[100]; //初始化两个数组 for(int i = 0;i < length;i++) { number[i] = str[i] - '0'; answer[i] = 0; } while(true) { for(int i = 0;i < length;i++) cout << c[number[i]][answer[i]]; cout <<endl; int k = length - 1; while(k >= 0) { /* 检查最后一位的字母是否已输出完 */ if(answer[k] < total [ number[k] ] - 1 ) { answer[k] ++; break; } else { /* 输出完的话将其置 0 ,将其上一位 的输出改变 */ answer[k] = 0; k--; } } if(k < 0 ) break; } }
假设输入为 234 ,从输出应该可以帮助你理解上面的代码
/* 输入数字:234 ADG ADH ADI AEG AEH AEI AFG AFH AFI BDG BDH BDI BEG BEH BEI BFG BFH BFI CDG CDH CDI CEG CEH CEI CFG CFH CFI 请按任意键继续. . . */
/* 书上使用的递归算法 只要输入中包含0和1两个不包含字母的值 就会失灵,中间循环断掉 一个不好用的解决方法: 把下面数组的前两位变成1 char total[10] = {0,0,3,3,3,3,3,4,3,4}; 即 char total[10] = {1,1,3,3,3,3,3,4,3,4}; */ #include <iostream> #include <string> using namespace std; void NumToWord(int* number,int* answer,int index,int n); // number[i] 为输入的数字的数组 // answer[i] 为 number[i] 所对应的数字所对应的第几个英文字母,初始化为第0个 int number[100]; int answer[100]; int length; char total[10] = {0,0,3,3,3,3,3,4,3,4}; char c[10][10] = { "", // 0 "", // 1 "ABC", // 2 "DEF", // 3 "GHI", // 4 "JKL", // 5 "MNO", // 6 "PQRS", // 7 "TUV", // 8 "WXYZ" // 9 }; int main() { string str; cout << "输入数字:"; cin >>str; /* 准备 */ //每个数字对应有几个英文字母 // 数组长度 length = str.length(); //初始化两个数组 for(int i = 0;i < length;i++) { number[i] = str[i] - '0'; answer[i] = 0; } NumToWord(number,answer,0,length); return 0; } void NumToWord(int* number,int* answer,int index,int n) { if(index == n) { for(int i = 0;i < n;i++) cout << c[number[i]][answer[i]]; cout << endl; return; } for(answer[index] = 0; answer[index] < total[number[index]]; answer[index]++) { NumToWord(number,answer,index+1,n); } }