题目描述
许多应用程序,如字处理软件,邮件客户端等,都包含了单词检查特性。单词检查是根据字典,找出输入文本中拼错的单词,我们认为凡是不出现在字典中的单词都是错误单词。不仅如此,一些检查程序还能给出类似拼错单词的修改建议单词。 例如字典由下面几个单词组成:
bake cake main rain vase
如果输入文件中有词vake ,检查程序就能发现其是一个错误的单词,并且给出 bake, cake或vase做为修改建议单词。
修改建议单词可以采用如下生成技术:
(1)在每一个可能位置插入‘a-'z'中的一者
(2)删除单词中的一个字符
(3)用‘a'-'z'中的一者取代单词中的任一字符
很明显拼写检查程序的核心操作是在字典中查找某个单词,如果字典很大,性能无疑是非常关键的。
你写的程序要求读入字典文件,然后对一个输入文件的单词进行检查,列出其中的错误单词并给出修改建议。
本题要求使用使用二叉排序树维护字典。为了防止有些人取巧,本题要求输出相应的二叉排序树后序遍历。
输入
输入分为两部分。
第一部分是字典,每个单词占据一行,最后以仅包含'#'的一行表示结束。所有的单词都是不同的,字典中最多10000个单词。
输入的第二部分包含了所有待检测的单词,单词数目不超过50。每个单词占据一行,最后以仅包含'#'的一行表示结束。
字典中的单词和待检测的单词均由小写字母组成,并且单词最大长度为15。
输出
第一行输出二叉排序树字典的后序遍历,每一个单词后面跟一个空格。
然后按照检查次序每个单词输出一行,该行首先输出单词自身。如果单词在字典中出现,接着输出" is correct"。如果单词是错误的,那么接着输出':',如果字典中有建议修改单词,则按照字典中出现的先后次序输出所有的建议修改单词(每个前面都添加一个空格),如果无建议修改单词,在':'后直接换行。
样例输入 Copy
i is has have be my more contest me too if award # me aware m contest hav oo or i fi mre #
样例输出 Copy
award contest be have has if me more too my is i 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
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int flag=0;
typedef struct node{
string s;
struct node *lchild=NULL,*rchild=NULL;
}node,*Node;Node Tree;
typedef struct dic{
string data;
int length=0;
}dic;//定义单词及长度
dic Diction[10001];//创建单词字典
int sum=0;//初始化单词下标
int Creatnode(Node &p,string e){//建立节点
if(!p){
Node s2=new node;
s2->s=e;s2->lchild=NULL;s2->rchild=NULL;Diction[sum].data=e;Diction[sum].length=Diction[sum].data.length();sum++;
p=s2;
}
else if(e<p->s)Creatnode(p->lchild,e);
else if(e>p->s)Creatnode(p->rchild,e);
}
int CreatTree(Node &Tree){//建立排序二叉树
Tree=new node;
string word;
cin>>word;
Tree->s=word;Diction[sum].data=word;Diction[sum].length=Diction[sum].data.length();sum++;
Tree->lchild=NULL;Tree->rchild=NULL;
while(cin>>word){
if(word[0]=='#')break;
Creatnode(Tree,word);
}
}
int Outnode(Node p){//输出节点
if(p->lchild)Outnode(p->lchild);
// cout<<p->s<<" ";
if(p->rchild)Outnode(p->rchild);
cout<<p->s<<" ";
}
int OutTree(Node Tree){//输出排序二叉树
if(Tree->lchild)Outnode(Tree->lchild);
// cout<<Tree->s<<" ";
if(Tree->rchild)Outnode(Tree->rchild);
cout<<Tree->s<<" ";
}
int judge(dic x,dic y){//判断长度相同的两个单词是否相等
int flag=1;
for(int i=0;i<x.length;i++)if(x.data[i]!=y.data[i]){
flag=0;break;
}
return flag;
}
void test1(dic x,dic y){//删除字母进行对比
dic s1=x;
int flag=1;int count=0;
for(int i=0,j=0;i<y.length;i++,j++){
if (count>1)break;
if(s1.data[j]!=y.data[i]){
j--;count++;
}
}
if(count==1){
cout<<" "<<x.data;flag=0;
}
}
void test2(dic x,dic y){//添加字母进行对比
dic s2=y;int flag=1;int count=0;
for(int i=0,j=0;i<x.length;i++,j++){
if (count>1)break;
if(s2.data[j]!=x.data[i]){
j--;count++;
}
}
if(count==1){
cout<<" "<<x.data;flag=0;
}
}
void test3(dic x,dic y){//改变字母进行对比
dic s3=y;int flag=1;int count=0;
for(int i=0,j=0;i<x.length;i++,j++){
if (count>1)break;
if(s3.data[j]!=x.data[i]){
count++;
}
}
if(count==1){
cout<<" "<<x.data;flag=0;
}
}
void test(dic s){
int flag=1;
for(int i=0;i<sum&&flag==1;i++){
if(flag){
if(s.length==Diction[i].length)if(judge(s,Diction[i])) {
cout<<s.data<<" is correct";flag=0;
}
}
}
if(flag)cout<<s.data<<":";
if(flag)for(int i=0;i<sum;i++){
if(s.length-1==Diction[i].length)test1(Diction[i],s);
if(s.length+1==Diction[i].length)test2(Diction[i],s);
if(s.length==Diction[i].length) test3(Diction[i],s);
} cout<<endl;
}
int main(){
CreatTree(Tree);
OutTree(Tree);
cout<<endl;
dic s;
while(cin>>s.data){
if(s.data[0]=='#')break;
s.length=s.data.length();
test(s);
}
return 0;
}