-
总时间限制:
- 2000ms 内存限制:
- 65536kB
-
描述
-
现在有一些英语单词需要做拼写检查,你的工具是一本词典。需要检查的单词,有的是词典中的单词,有的与词典中的单词相似,你的任务是发现这两种情况。单词A与单词B相似的情况有三种:1、删除单词A的一个字母后得到单词B;2、用任意一个字母替换单词A的一个字母后得到单词B;3、在单词A的任意位置增加一个字母后得到单词B。你的任务是发现词典中与给定单词相同或相似的单词。
输入
-
第一部分是词典中的单词,从第一行开始每行一个单词,以"#"结束。词典中的单词保证不重复,最多有10000个。
第二部分是需要查询的单词,每行一个,以"#"结束。最多有50个需要查询的单词。
词典中的单词和需要查询的单词均由小写字母组成,最多包含15个字符。
输出
- 按照输入的顺序,为每个需要检查的单词输出一行。如果需要检查的单词出现在词典中,输出“?x is correct",?x代表需要检查的单词。如果需要检查的单词没有出现在词典中,则输出"?x: ?x1 ?x2 ...?xn",其中?x代表需要检查的单词,?x1...?xn代表词典中与需要检查的单词相似的单词,这些单词中间以空格隔开。如果没有相似的单词,输出"?x:"即可。 样例输入
-
i is has have be my more contest me too if award # me aware m contest hav oo or i fi mre #
样例输出
me is correct aware: award m: i my me contest is correct hav: has have oo: too or: i is correct fi: i mre: more me
这题新学会了一个BK树。。照着算法打 但不能透彻理解。编辑距离的应用。
推荐链接。http://www.matrix67.com/blog/?s=bk%E6%A0%91
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<assert.h> #include<ctype.h> #include<stdlib.h> #define min(a,b) (a)>(b)?(b):(a) using namespace std; struct word{ int shunxu; char str[20]; }; struct node { word wo; struct node* child[16];//最多15个字符 }*root; int flag=0; word ans[3000]; int anst=0; int cal_juli(char *a,char *b)//计算编辑距离 { int la = strlen(a); int lb = strlen(b); int i,j; int s[20][20]; for(i=0; i<=la ; i++) s[i][0] = i; for(i=0; i<=lb; i++) s[0][i] = i; for(i = 1; i <= la; i++) for(j = 1; j <= lb; j++) { int cost; if(a[i-1] == b[j-1])cost = 0; else cost = 1; s[i][j] = min(min(s[i][j-1]+1,s[i-1][j] + 1),s[i-1][j-1]+cost); } return s[la][lb]; } node* newnode( )//初始化节点。 { node *t; t =(node*)malloc(sizeof(node)); for(int i=0; i<=15; i++) t->child[i] = NULL; return t; } void insert( node *T ,word ss)//照算法建树 { int juli = cal_juli(T->wo.str,ss.str); if( !T->child[juli] ) { T->child[juli] = newnode(); T->child[juli]->wo = ss; } else { insert( T->child[juli],ss); } } void query( node * T,char *str1 ) { if(!T)return; int juli = cal_juli(T -> wo.str, str1 ); if( juli == 0 ) { flag = 1; printf("%s is correct",str1); } else { if(juli == 1){ ans[anst++] = T->wo;} if(!flag) for(int i=juli-1; i<=juli+1&&i<=15; i++) if(T->child[i]) query(T->child[i],str1); } } bool cmp(word a, word b) { return a.shunxu < b.shunxu; } int main() { //freopen("in.txt","r",stdin); root = newnode(); scanf("%s",root->wo.str); root->wo.shunxu = 0; word temp; int cnt=1; while(scanf("%s",temp.str)&&temp.str[0] != '#') { temp.shunxu = cnt++; insert(root,temp); } char dd[20]; while(scanf("%s",dd)&&dd[0] != '#') { flag = 0; anst=0; query( root, dd); if(!flag) { printf("%s:",dd); sort(ans,ans+anst,cmp);//因为插入时是无序的 需要按要求排序输出。。 for(int i = 0; i < anst; i++) printf(" %s",ans[i].str); } printf("\n"); } return 0; }