题目和思路来自编程之美
题目:
电话的号码盘一般可以用于输入字母,而且一个数字可以对应多个或者0个字母。如用2可以输入A、B、C,用3可以输入D、E、F等。
给出一个号码,它可以对应许多个字母组合。如号码5869872,它对应的字母组合可以是JTMWTPTA、JTMWTB······
问题(1)给出一个电话号码,设计程序,从该电话号码对应的这些字母组合中,找到一个有意义的单词来表述一个电话号码。
举例:单词"computer"来描述号码26678837。
问题(2)对于一个号码,是否可以用一个单词代表?(否)怎样才是最快的方法?
综合这两个问题,其实就是找出最快的方法,使得找到一个有意义的单词与数字对应?
思路:
方法(1)对字母集合进行深搜 + 字典匹配
<1>直接对每一个数字对应的字母集合进行深搜,类似元素的组合求出所有字母集合
<2>对每一种组合都与字典匹配,有意义则输出
代码:这里指给出深搜求字母组合的递归代码
#include <iostream>
#include <assert.h>
using namespace std;
void Perm(char strSet[10][10],int nArrTeleNum[],int nLen,int nCur,int nPos,char strWord[])
{
if (nCur == nLen)
{
for (int i = 0;i <= nPos;i++)
{
cout<<strWord[i];
}
cout<<endl;
return;
}
char* pStr = strSet[nArrTeleNum[nCur]];
int nCurStrLen = strlen(pStr);
if (nCurStrLen == 0)
{
Perm(strSet,nArrTeleNum,nLen,nCur + 1,nPos,strWord);
}
else
{
for (int i = 0;i < nCurStrLen;i++)
{
strWord[nPos] = pStr[i];
Perm(strSet,nArrTeleNum,nLen,nCur + 1,nPos + 1,strWord);
}
}
}
int main()
{
int nArrTeleNum[10];//存放电话号码
int nLen;//本次输入电话号码个数
char strWord[10];//产生的单词集合
char strSet[10][10]=
{
"","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"
};
cin>>nLen;
for (int i = 0;i < nLen;i++)
{
cin>>nArrTeleNum[i];
assert(nArrTeleNum[i] >= 0 && nArrTeleNum[i] <= 9);
}
Perm(strSet,nArrTeleNum,nLen,0,0,strWord);
system("pause");
return 1;
}
迭代代码:
书中给出了一个不确定循环个数的代码,挺有意思。可以一看。
#include<iostream>
using namespace std;
const int MaxLength = 9;
char c[10][10] = {"", "", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};
int total[10] = {0,0,3,3,3,3,3,4,3,4};
int main()
{
int number[MaxLength] = {3,4,5}; //本例输入数字3,4,5
int answer[MaxLength] = {0};
int len = 3;
while(true)
{
for(int i = 0; i < len; i++)//每当有一个数字改变了,都是一种排列,直接输出
printf("%c", c[number[i]][answer[i]]);
printf("\n");
int k = len - 1;//其中某一位改变后,都从最后一个数开始重新赋值,形成新排列
while(k >= 0)
{
if(answer[k] < total[number[k]] - 1)//其中某一位改变后,也是一种新排列,不再继续循环
{
answer[k]++;
break;
}
else//第k位的数已经全部放完,此时需要设置第k - 1位。
{
answer[k] = 0;//为了下一次下标++后不越界,需要把第k位置0
k--;
}
}
if(k < 0)//所有元素均处理完了。
break;
}
return 0;
}
方法(2)离线求出每一个数字组合对应的字母组合 +在线字典匹配
这里代码不再给出。
方法(3)字典单词转化为数字 + 与给出数字进行匹配
思路:把字典中的单词转换为数字,之后把转换后的数字与给出的数字进行匹配。
这里代码不再给出。