传送门:http://poj.org/problem?id=1035
题意:输入很多单词构成一部字典,按#结束字典输入,再输入一些单词,按#结束,查询后来输入的单词是否在字典中存在,若存在则输出 XXXX is correct 若不在字典中存在,则先输出XXXX:,再对该单词进行 删除,替换,插入 操作,判断操作后的单词是否在字典中存在,若存在则输出,若存在多个,则按 这些单词在该字典的输入顺序 输出操作后的单词,若经操作后依然没有该单词,则再输出回车即可。
思路:用Trie树建立字典,对于后来输入的单词在字典中查询,有则输出XXXX is correct,没有则进行 删除,替换,插入 操作,看有无该单词在字典中,有则将该单词放于一数组中,得到所有单词后再排序输出。。
注意:该题有个陷阱 如样例:
be
#
bee
#
若没有进行重判则会输出bee: be be
因此要增加一重判。
代码如下:
//Memory:16624KB Time:204ms
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxnode=150001;
char str[16];
struct node
{
char str[17]; //17的原因是若该单词的长度是15,加上'\0'就是16,经过插入操作后就会变成17了
int index;
}ans[19501]; //答案存储的数组
int cnt;
struct Trie //建立字典树
{
int ch[maxnode][27];
int val[maxnode];
int sz;
void init(){sz=1;memset(ch,0,sizeof ch);memset(val,0,sizeof val);}
int idx(char c){return c-'a';}
void insert(char *s,int v)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
ch[u][c]=sz++;
u=ch[u][c];
}
val[u]=v; //val是标记数组,用于标记是否为单词结尾并且是第几个单词,用于后面排序
}
int find(char *s)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
return 0;
u=ch[u][c];
}
return val[u];
}
}t;
void rep(char *s,int len) //替换
{
int x;
char temp[16];
for(int i=0;i<len;i++)
{
for(char j='a';j<='z';j++)
{
strcpy(temp,s);
temp[i]=j;
if(x=t.find(temp))
{
strcpy(ans[cnt].str,temp);
ans[cnt++].index=x;
}
}
}
}
void Del(char *s,int len) //删除
{
int x;
char temp[16];
for(int i=0;i<len;i++)
{
for(int j=0;j<i;j++)
temp[j]=s[j];
for(int j=i;j<len-1;j++)
temp[j]=s[j+1];
temp[len-1]='\0';
if(x=t.find(temp))
{
strcpy(ans[cnt].str,temp);
ans[cnt++].index=x;
}
}
}
void incer(char *s,int len) //插入
{
int x;
char temp[17]; //插入的temp要为17,理由同上
for(int i=0;i<=len;i++)
for(char j='a';j<='z';j++)
{
for(int k=0;k<i;k++)
temp[k]=s[k];
temp[i]=j;
for(int k=i;k<len;k++)
temp[k+1]=s[k];
temp[len+1]='\0';
if(x=t.find(temp))
{
strcpy(ans[cnt].str,temp);
ans[cnt++].index=x;
}
}
}
bool cmp(node a,node b)
{
return a.index<b.index;
}
int main()
{
t.init();
int len;
int v=1;
while(1) //字典树的单词插入
{
gets(str);
if(str[0]=='#') break;
t.insert(str,v);
v++;
}
while(1)
{
gets(str);
if(str[0]=='#') break;
if(t.find(str))
printf("%s is correct\n",str);
else
{
cnt=0;
len=strlen(str);
rep(str,len); //替换
Del(str,len); //删除
incer(str,len); //插入
sort(ans,ans+cnt,cmp);
printf("%s:",str);
if(cnt) printf(" %s",ans[0].str);
for(int i=1;i<cnt;i++) //重判
if(ans[i].index!=ans[i-1].index)
printf(" %s",ans[i].str);
printf("\n");
}
}
}