zufe 1932: 语音识别 (模拟_有点烦)

Description

       如果使用姓氏在数据库中查找一个人的名字, 仅当你准确知道名字是如何拼写的时候才会成功. 不过, 假设你正在运行一个航班预订系统, 并且需要在不知道精确的拼写时查找名字. 你将需要一种方法, 基于名字的发言对他们进行编码. 然后, 查找将输出具有类似读音的名字的表项. 例如, 你将希望相同的查找可以发现DicksonDixon.

       Soundex算法就是这样一个根据发音来编码姓名的算法. 它使得读音相似的名字具有相同的编码. 该系统被广泛使用. 它基于语言学家和速记员所熟悉的一个概念: 可以只基于辅音字母来区分英文单词和名字. 例如, 注意当只有辅音字母表示这个句子的最后几个单词(the last few words of this sentence when represented by consonants alone) : th lst fw wrds f ths sntnc whn rprsntd b cnsnnts alne. 其含义很清晰, 即使拼写看上去有点奇怪.

       Soundex读取一个名字(只包含大小写字母), 先把所有字母转化成大写的, 保留第一个字母,从第二个输入的字母开始,对于每个字母赋予7个值之一, 其中A, E, I, O, U, H, W, Y对应0; B, F, P, V对应1, C, G, J, K, Q, S, X, Z对应2, D, T对应3; L对应4; M, N对应5; R对应6; 在赋予所有字母各自的数字之后, 将先删除0, 再把连续重复出现的相同数字减少到一位(实际上会删除成对出现的辅音字母以及重复出现的相同辅音字母组). 代码中使用了前三个余下的数字. 如果剩下的数字少于三个, 将用0填充代码. Soundex代码包含要编码的单词或名字的首字母, 其后接着三位数字的代码. 这样Lincoln转换为L524.

       当我们使用Soundex, 名字DicksonDixon具有相同的代码: D250. Smith, Smyth, Smythe也将分享共同的Soundex代码. Soundex方法可以有效地用于从数据库中检索名字.

       现给出若干个名字, 请分别输出他们的Soundex代码.

Input

输入文件包含多个测试数据, 每个测试数据占一行, 为一个长度不超过20的英文字母字符串. 输入到文件尾结束.

Output

对于输入的每个数据,输出相应的结果。

 

Sample Input

 
Dickson
Dixon
dixon
Smith
Smyth
Smythe

Sample Output

  
  
D250
D250
D250
S530
S530
S530

   
   

   
   

   
   
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>;
using namespace std;
char s[40],ans[40];
map<char,char>pre;
int main()
{
	int i,j,len,k,t;
	pre['A']=pre['E']=pre['I']=pre['O']=pre['U']=pre['H']=pre['W']=pre['Y']='0';
	pre['B']=pre['F']=pre['P']=pre['V']='1';
	pre['C']=pre['G']=pre['J']=pre['K']=pre['Q']=pre['S']=pre['X']=pre['Z']='2';
	pre['D']=pre['T']='3';
	pre['L']='4';
	pre['M']=pre['N']='5';
	pre['R']='6';
	while(cin>>s) {
		len=strlen(s);
		for(i=0;i<len;i++) {
			if(s[i]>90) s[i]=s[i]-32;
			else s[i]=s[i];
			if(i) s[i]=pre[s[i]];
		}
		k=1;t=1;
		ans[0]=s[0];
		for(i=1;i<len;i++) {
			while(s[i]=='0' && i<len ) i++;
			if(i<len)s[k++]=s[i];
		}
		for(i=1;i<k;i++) {
			while(s[i]==s[i-1]&&i<len) i++;
			if(i<len) ans[t++]=s[i];
		}
		while(t<4) ans[t++]='0';
		for(i=0;i<4;i++) cout<<ans[i];
		cout<<endl;
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值