对于号码5869872,可以依次输出其代表的所有字母组合,如JTMWTPA、JTMWTPB.....
#include <iostream>
#include <string>
#include <vector>
using namespace std;
char keyBoard[10][10] =
{
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"
};
int keyLength[10] = {0, 0, 3, 3, 3, 3, 3, 4, 3, 4};
vector<char> result;
void printCombine(const char *numbers, int index)
{
if (numbers == NULL)
return;
if (index == strlen(numbers))
{
copy(result.begin(), result.end(), ostream_iterator<char>(cout, " "));
cout << endl;
return;
}
for (int i = 0; i < keyLength[numbers[index] - '0']; i++)
{
result.push_back(keyBoard[numbers[index] - '0'][i]);
printCombine(numbers, index + 1);
result.pop_back();
}
}
void main()
{
printCombine("422", 0);
}编程之美上的解法,多重for循环,看得头晕。。。
void printCombine(const char *numbers)
{
int answer[2];
for (answer[0]= 0; answer[0] < keyLength[numbers[0] - '0']; answer[0]++)
{
for (answer[1] = 0; answer[1] < keyLength[numbers[1] - '0']; answer[1]++)
{
for (int i = 0; i < 2; i++)
cout << keyBoard[numbers[i] - '0'][answer[i]];
cout << endl;
}
}
}根据递归解法,可以想象本题的实质不过是进制的变种而已,前面的习题是10进制,这个是N进制,不同位的最大值不一样,判断并取进位
void printCombine2(int *numbers, int size)
{
if (numbers == NULL || size <= 0)
return;
int *index = new int[size];
if (index == NULL)
return;
for (int i = 0; i < size; i++)
index[i] = 0;
int pos = size - 1;
bool flag = false;
while (true)
{
if (pos < 0)
break;
for (int i = 0; i < size; i++)
printf("%c", keyBoard[numbers[i]][index[i]]);
printf("\n");
index[size - 1]++;
for (pos = size - 1; pos >= 0; pos--)
{
if (flag == true)
index[pos]++;
if (index[pos] == keyLength[numbers[pos]])
{
index[pos] = 0;
flag = true;
continue;
}
else
{
flag = false;
break;
}
}
}
}不过编程之美上给出了似乎更为简洁的解答,其实实质一样
void printCombine2(int *numbers, int size)
{
if (numbers == NULL || size <= 0)
return;
int *index = new int[size];
if (index == NULL)
return;
for (int i = 0; i < size; i++)
index[i] = 0;
int pos = size - 1;
bool flag = false;
while (true)
{
if (pos < 0)
break;
for (int i = 0; i < size; i++)
printf("%c", keyBoard[numbers[i]][index[i]]);
printf("\n");
index[size - 1]++;
for (pos = size - 1; pos >= 0; pos--)
{
if (flag == true)
index[pos]++;
if (index[pos] == keyLength[numbers[pos]])
{
index[pos] = 0;
flag = true;
continue;
}
else
{
flag = false;
break;
}
}
}
}
还是书上给出的递归程序靠谱,不需要保存额外信息:
void printCombine3(int *numbers, int *answer, int index, int size)
{
if (numbers == NULL || size <= 0)
return;
if (index == size)
{
for (int i = 0; i < size; i++)
{
printf("%c", keyBoard[numbers[i]][answer[i]]);
}
printf("\n");
system("pause");
return;
}
for (answer[index] = 0; answer[index] < keyLength[numbers[index]]; answer[index]++)
{
printCombine3(numbers, answer, index + 1, size);
}
}
博客探讨了如何将电话号码5869872转换为对应的字母组合,通过对比编程之美中复杂的多重循环解法与书中的递归程序,强调了递归解法的简洁高效,无需额外保存信息。
1728

被折叠的 条评论
为什么被折叠?



