您的位置:首页 > 其它

电话号码对应英语单词 结构之法 2

2014-04-14 10:00 197 查看
电话号码对应英语单词的问题

电话的号码盘一般可以用于输入字母。如用可以输入A、B、C,用3可以输入D、E、F等。对于号码5869872,可以依次输出其代表的所有字母组合。如:JTMWTPA、JTMWTPB......

1. 你是否可以根据这样的对应关系设计一个程序,尽可能快地从这些字母组合中找到一个有意义的单词来表述一个电话号码呢?如:可以用单词“computer”来描述号码26678837.

2. 对于一个电话号码,是否可以用一个单词来代表呢?怎样才是最快的方法呢?显然,肯定不是所有的电话号码都能够对应到单词上去。但是根据问题1的解答,思路相对比较清晰。

解题思路:

构造出相应的排列树,从而可以简单地通过遍历所有的叶子节点,得到其所代表的“单词”集合。

问题一的解法一:直接循环法:

total :中存放各个数字所能代表的字符总数

number : 存放电话号码

answer : 存放数字目前所代表的字符在其所能代表的字符集中的位置,其中初始化时answer[i]=0

#include<iostream>
#include<string>
using namespace std;
//循环实现
int main()
{
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 number[12];//电话号码,电话号码的长度最长不能超过12个数字
int answer[12]={0};//数字目前所代表的字符在其所能代表的字符集中的位置
cout<<"请输入电话号码的长度"<<endl;
int n;//记录电话号码的实际长度
cin>>n;

cout<<"请输入一个电话号码,每两个数字之间用空格隔开(如:3 2 1)"<<endl;
//1111///cout<<answer[0]<<answer[1]<<answer[2]<<answer[3]<<endl;
//1111///cin>>number[0]>>number[1]>>number[2]>>number[3];
for(int i=0;i<n;i++)
{
cin>>number[i];
}
while(true) //核心代码,言简意赅,非常经典
{
for(int i=0;i<n;i++)
{
cout<<c[number[i]][answer[i]];
}
cout<<endl;
int k=n-1; // k=TelLength-1
while(k>=0)
{
if(answer[k]<total[number[k]]-1)
{
answer[k]++;
break;
}
else
{
answer[k]=0;
k--;
}
}
if(k<0) break;

}
return 0;
}

问题1的解法二:递归的方法

核心代码如下: index说明对电话号码的第几位进行循环移位,n为电话号码的位数。初始时调用RecursiveSearch(number,answer,0,n)

个人觉得有点像全排列的递归算法:

void RecursiveSearch(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 ;
}
else
{
for(answer[index]=0;answer[index]<total[number[index]];answer[index]++)
{
RecursiveSearch(number,answer,index+1,n);
}
}
}

问题2的解法一:

利用问题1的算法,把该电话号码所对应的字符全部计算出来,然后去匹配字典,判断是否有答案。

问题2的解法二:

如果查询的次数较多,可直接把字典里面的所有单词都按照这种转换规则转换为数字,并存到文件中,使之成为另一本数字字典,然后,通过对这个电话号码查找表的方式来得到结果。事实上已经有相应的Web应用出现了,网站服务器中存放着经过转换的数字字典,客户端通过浏览器可以很方便快捷地进行查询。但若查询的次数较少,比如只在Client查一两次,那么翻译整本数字字典就不值得了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: