1:拼写检查

总时间限制: 
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;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值