POJ1035:拼写检查-AC代码(2180kB 1471ms)(求编辑距离、动态规划)

1035:拼写检查

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

解答:

【标记】 记str[10000]用来存储字典,count为字典内单词总数。k、i、j分别代表求编辑距离时字典单词编号、字典单词前i个字符、测试用例前j个字符。dp[i][j]表示取字典单词前i个字符、测试用例前j个字符时的编辑距离。char temp[20]为输入,in表示temp转换为string。x表示终止时的"#",dis是最终的编辑距离,

【思路】用map存储字典,对每一个测试用例,如果map中有它对应的int,就说明是correct的。否则的话,针对当前测试用例,遍历所有字典单词,求当前用例与字典单词的编辑距离,如果编辑距离是1,就是相似单词。

【注意】编辑距离初始化、求三个值的min

#include<iostream>
#include<cstring>
#include<map>
using namespace std;
std::map<string,int> m;
struct ss
{
	string s;
}str[10000];
int main(int argc, char const *argv[])
{
	string in,x;
	int count,i,j,k,dis,dp[20][20],p;
	char temp[20];
	x="#";
	count=0;
	while(scanf("%s",&temp))
	{
		in=temp;
		if(x==in)break;
		m[in]=1;
		str[count++].s=in;
	}
	while(scanf("%s",&temp))
	{
		in=temp;
		if(x==in)break;
		
		if(m[in]==1)
			cout<<in<<" is correct"<<endl;
		else
		{
			cout<<in<<":";
            //对每一个测试用例求编辑距离
			for(k=0;k<count;k++)
			{  
            //初始化编辑距离dp
				for(i=0;i<=str[k].s.size();i++) dp[i][0]=i;
				for(j=0;j<=in.size();j++)dp[0][j]=j;
				dis=0;
            //求编辑距离
				for(i=1;i<=str[k].s.size();i++)
				{
					for(j=1;j<=in.size();j++)
					{
						if(str[k].s[i-1]==in[j-1])dp[i][j]=dp[i-1][j-1];
						else
						{
							p=min(dp[i-1][j],dp[i][j-1]);
							dp[i][j]=min(p,dp[i-1][j-1])+1;
						}
					}
				}
				dis=dp[str[k].s.size()][in.size()];
				if(dis==1)
					cout<<" "<<str[k].s;
			}
			printf("\n");
		}
	}
	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值