电话拨号键盘的数字键会对应若干个英文字母。比如说,2可以是A,B或C,3可以是D,E或F,等等。1和0没有对应的,可以忽略。
a. 找出这个电话号码所能代表的所有字符串组合A。给定一个单词列表B(请设计一个数据结构来储存单词列表B),在问题a找到的字符串组合A中,找出这样一些字符串:该字符串的所有子串中至少有一个子串存在于单词列表B中。b.备注:请实现最高效的查询方法。
现在给定一个电话号码,请编写代码实现以下功能比如:a. 它可以对应:AD, AE, AF, BD, BE, BF, CD, CE, CF;b. BE可以在字典中找到(BE是它自己的一个子串,并假设字典中不包含单字母)
思路:
1. 首先要判断给定的数字字符串是否合法(isnumber()方法),即是否只包含0~9的数字,如果还包含其他,则直接返回空;
2. 其次要将每个数字所对应的字符串保存起来,这里我使用的是map,key是数字,value是数字所对应的字符串;
3. 采用递归的方式将数字所代表的字母连接起来;举例:23,则对应的是ABC,DEF,此时首先选择A,然后选择D,得到一个结果AD,选择E,得到一个结果AE,选择F,得到结果AF,选择B,然后选择D,得到BD,以此类推......
4.遍历字符串组合A,查找是否包含字典B中的字符,将包含的字符串存储。
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
map<char,string> numc;
bool isnumber(string p){//判断是不是输入的电话号码
if(p.size()<1)return false;
for(unsigned int i=0;i<p.length();i++){
if(p[i]<'0'||p[i]>'9') return false;
}
return true;
}
void lettercore(string p,int index,string ch,vector<string> &res){
if(index==p.length()){
res.push_back(ch);
return;
}
char c=p.at(index);
//if(c=='0'||c=='1') lettercore(p,index+1,ch,res);
for(unsigned int i=0;i<numc[c].length();i++){
ch[index]=numc[c].at(i);
lettercore(p,index+1,ch,res);//用递归实现字母的组合
}
}
vector<string> letters(string phonenum){
vector<string> res;
if(phonenum.size()<1) return res;
if(!isnumber(phonenum)) return res;
string pother;//先将电话号码中的0和1去掉
for(unsigned int i=0;i<phonenum.length();i++){
if(phonenum[i]=='0'||phonenum[i]=='1') continue;
else pother.push_back(phonenum[i]);
}
string ch;
ch.resize(pother.length());
lettercore(pother,0,ch,res);
return res;
}
vector<string> indict(vector<string> const B,vector<string> A){
vector<string> re;
bool *isview=new bool[A.size()];
for(unsigned int i=0;i<A.size();i++){
isview[i]=false;
}
for(unsigned int i=0;i<A.size();i++){
for(unsigned int j=0;j<B.size();j++){
if((A[i].find(B[j])!=A[i].npos)&&(!isview[i])) {
re.push_back(A[i]);
isview[i]=true;
}
}
}
return re;
}
void print(vector<string> st){//输出
vector<string>::iterator it=st.begin();
for(;it!=st.end();it++){
cout<<*it<<endl;
}
}
void main()
{
numc.insert(make_pair('0',""));
numc.insert(make_pair('1',""));
numc.insert(make_pair('2',"ABC"));
numc.insert(make_pair('3',"DEF"));
numc.insert(make_pair('4',"GHI"));
numc.insert(make_pair('5',"JKL"));
numc.insert(make_pair('6',"MNO"));
numc.insert(make_pair('7',"PQRS"));
numc.insert(make_pair('8',"TUV"));
numc.insert(make_pair('9',"WXYZ"));
string phone;
cin>>phone;
vector<string> A,result;
A=letters(phone);
cout<<"这个电话号码代表的所有字符串:"<<endl;
print(A);
vector<string> B;
string temp;
cout<<"输入单词列表B:"<<endl;
while(cin>>temp)
B.push_back(temp);
cin.clear();
result=indict(B,A);
cout<<"子串可以在字典中找到的字符串:"<<endl;
print(result);
cin.get();
}
自己这样写的也不知道对不对,但是自己测试了还是能通过的。如果是手机电话号码(11位)的话,找出所有的字符串组合花费较长时间,我在VS2010中运行花了20s。