SOUNDEX(c1)

SOUNDEX(c1)
【功能】返回字符串参数的语音表示形式
【参数】c1,字符型
【返回】字符串
【说明】相对于比较一些读音相同,但是拼写不同的单词是非常有用的。
计算语音的算法: 
  1.保留字符串首字母,但删除a、e、h、i、o、w、y 
  2.将下表中的数字赋给相对应的字母 
  (1) 1:b、f、p、v 
  (2) 2:c、g、k、q、s、x、z 
  (3) 3:d、t 
  (4) 4:l 
  (5) 5:m、n 
  (6) 6:r 
  3. 如果字符串中存在拥有相同数字的2个以上(包含2个)的字母在一起(例如b和f),或者只有h或w,则删除其他的,只保留1个 
  4.只返回前4个字节,不够用0填充 
  示例: 
  soundex('two'),soundex('too'),soundex('to'),他们的结果都是T000 
  soundex('cap'),soundex('cup'),他们的结果都是C100 
  soundex('house'),soundex('horse'),他们的结果都分别是H200,H620

#include <stdio.h> #include <string.h> #include <ctype.h> #include <math.h> #include <stdlib.h> #define min(a,b) (a<b?a:b) #define ll long long #define MAX_WORD 50 #define MAX_NUM 500000 #define max2(a,b) ((a)>(b)?(a):(b)) int **Dp, MaxDP=3300; char key[MAX_WORD]; //key保存错误词确保可以传入cmp1函数 int min3(int a,int b,int c){ int min=a<b?a:b; return min<c?min:c; } int error2(char *s){ fprintf(stderr,"%s\n",s); exit(-1); } int initDP(){ int i; Dp = (int **)malloc(MaxDP*sizeof(int *)); for(i=0; i<MaxDP; i++) Dp[i] = (int *)malloc(MaxDP*sizeof(int)); return 0; } int editdistDP(char *str1, char *str2) { int i,j; int len1, len2; static int flag=0; (flag++) ? 1 : initDP(); len1 = strlen(str1)+1; len2 = strlen(str2)+1; (max2(len1,len2)>=MaxDP) ? error2("DP memory error!") : len1; for (i=0; i<=len1; i++) { for (j=0; j<=len2; j++) { if (i==0) Dp[i][j] = j; else if (j==0) Dp[i][j] = i; else if (str1[i-1] == str2[j-1]) Dp[i][j] = Dp[i-1][j-1]; else Dp[i][j] = 1+min3(Dp[i][j-1], Dp[i-1][j], Dp[i-1][j-1]); } } return Dp[len1][len2]; } int cmp(const void *a, const void *b) { return strcmp((const char *)a, (const char *)b); } int cmp1(const void *a, const void *b) { char *pa = (char *)a; char *pb = (char *)b; return editdistDP(pa, key) - editdistDP(pb, key); } char word[MAX_NUM][MAX_WORD],d[MAX_NUM][MAX_WORD]; int f[MAX_NUM]; int main(){ FILE* in=fopen("in.txt", "r"); FILE* dict=fopen("dict.txt","r"); int n=0;//n是字典单词数 while (fscanf(dict,"%s",d[n])!=EOF) { d[n][strcspn(d[n],"\n")]='\0'; n++; } char c; int num=0,ci=0,fl=1;//num是句子中的单词数 while(fscanf(in,"%c",&c)!=EOF){ if(isalpha(c)){ if(fl<=0) { word[num][ci]='\0'; num++,ci=0; } if(fl!=-1&&num!=0) f[num-1]=1;//f判断的是这个单词后面有无断句,即这个单词能不能当第一位 fl=1; if(isupper(c)) c=tolower(c); word[num][ci++]=c; } else if((c==' ')||(c=='\t')) fl=0; else//c是其他字符 fl=-1; } int id[MAX_NUM]; ci=0;//保存错误单词编号,ci是错误单词数 for(int i=0;i<num;i++) { char **result=(char **)bsearch(word[i],d,n,sizeof(char [MAX_WORD]),cmp); if (result==NULL) { id[ci++]=i; f[i]=-1;//这个单词错了肯定不能当第一位了 } } char s[1010][MAX_WORD];//保存所有推荐词 for(int i=0,k=0;i<ci;i++) { if(id[i]!=0&&f[id[i]-1]==1)//不是第一位,有前缀词 { strcpy(key,word[id[i]]); for(int j=0;j<num;j++) { if((strcmp(word[j],word[id[i]-1])==0)&&(f[j]!=0)&&(f[j+1]!=-1)&&(word[j+1][0]!=0)) {//前缀词相同且前缀词与下位相连且下一位不为0或出错 int f2=1; for(int g=0;g<k;g++) { if(strcmp(s[g],word[j+1])==0) f2=0; } if(f2) strcpy(s[k++],word[j+1]); } } if(k!=0) qsort(s,k,sizeof(s[0]),cmp1); //对推荐词排序 printf("%s : %s -> ",word[id[i]-1],word[id[i]]); if(k==0) { printf("No suggestion"); } else { int e=0; while(cmp1(s[e],s[e+1])==0)e++; qsort(s,e+1,sizeof(s[0]),cmp); for(int c1=0;c1<=e;c1++) { printf("%s",s[c1]); if(c1!=e) printf(","); } } } memset(s,0,sizeof(s)); k=0; } fclose(in); fclose(dict); } 修改代码
06-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值