编程理解——电话号码对应的字符串


电话拨号键盘的数字键会对应若干个英文字母。比如说,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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值