/*
poj 1035 Spell Checker
题目大意:
给定一堆字符串作为字典,判断单词是否在字典中,或则可以由字典中的哪些单词演化得到?
演化规则:单词b可以通过单词a添加、删除或者替换一个字母得到。
解题思路:
因为题目要求需要按照字典中单词的顺序输出所有相似的单词(可演化得到目的单词的),因此
没法使用Trie或者hash之类的快速查找结构 -- 因为不是单纯查找是否存在!
采用最直接的方法,顺序遍历字典,判断每个单词是否与目的单词相似或者相同。
如果相同,停止遍历,输出结果。
如果相似,记录单词下标,直到字典遍历完毕,输出所有相似单词。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
namespace {
using namespace std;
const int STR_LEN_MAX = 15;
const int DIC_SIZE_MAX = 10000;
char DIC[DIC_SIZE_MAX][STR_LEN_MAX+1]; // 单词表
unsigned char L[DIC_SIZE_MAX]; // 单词长度记录表
unsigned short CL[DIC_SIZE_MAX]; // 近似链,记录相近单词所在字典的下标
// 计算两单词不同的字符个数
int diff(const char *pWord1, int l1, const char *pWord2, int l2)
{
int i=0, j=0;
int count = 0;
for (i=0, j=0; i<l1&&j<l2;)
{
if (pWord1[i]!=pWord2[j])
{
if (l1<l2) // 增加一个字符的情况
++j;
if (l1 == l2 ) // 替换的情况,同时++
{
++i; ++j;
}
if (l1 > l2 ) // 删除一个字符的情况
++i;
++count;
}
else
{
++i; ++j;
}
}
count += ((l2-j)+(l1-i)); // 要把没比完的字符个数加上
return count;
}
}
int main()
{
int dicSize = 0;
while (EOF!=scanf("%s", DIC[dicSize]) && DIC[dicSize][0]!='#')
{
L[dicSize] = strlen(DIC[dicSize]);
++dicSize;
}
int l, num;
char word[STR_LEN_MAX+1];
while (EOF!=scanf("%s", word) && word[0]!='#')
{
l = strlen(word);
num = 0;
int i;
for (i=0; i<dicSize; i++)
{
// 这3种情况之外,不处理
if (l!=L[i] && l!=L[i]-1 && l!=L[i]+1)
continue;
int dn = diff(DIC[i], L[i], word, l);
if (dn == 0)
{
num = 0; // DIC[i]与单词word完全相同,停止迭代
break;
}
else if (dn == 1)
{
CL[num++] = i; // DIC[i]与单词word相似,记录下标
}
else
{
// do nothing
}
}
if (num==0 && i!=dicSize)
{
printf("%s is correct\n", word);
}
else
{
printf("%s:", word);
for (int i=0; i<num; i++)
{
printf(" %s", DIC[CL[i]]);
}
printf("\n");
}
}
}
poj 1035 Spell Checker
最新推荐文章于 2019-02-20 20:07:21 发布