POJ 1035 Spell Check 字符串处理

被这样的题目忽悠了,一开始以为使用Trie会大大加速程序的,没想到,一不小心居然使用Trie会超时。

最后反复试验,加点优化,终于使用Trie是可以过的,不过时间大概难高于1500ms,一不小心就会超时。

看来这是一道专门卡Trie的题目,只好放弃不使用Trie了。

也得出点经验,如果字符串很多,如本题有1万个字符串的,那么还是不要使用Trie吧,否则遍历一次这样的Trie是十分耗时的,2s以上。

于是使用暴力搜索法了,这里的技巧是可以使用优化技术:

1 剪枝:这里直接分组搜索,分组是按照字符串的长度分组

2 对比查找是合法字符的时候不要使用Edit Distance,而是使用计算字符差别的方法判断是否是合法字符的。

有了这两个技巧就不算纯粹的暴力法了,最后速度还是挺快的。

#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

const int MAX_N = 10001;
const int ALP_SIZE = 26;
const int WORD_SIZE = 18;
inline int min(int a, int b) { return a < b ? a : b; }
inline int max(int a, int b) { return a > b ? a : b; }

struct strNode
{
	int num;
	char str[WORD_SIZE];
	bool operator<(const strNode &str) const
	{
		return num < str.num;
	}
};

char word[WORD_SIZE];
vector<strNode> dict[WORD_SIZE];
vector<strNode> res;
int num;

inline bool getReplacing(int len, char di[])
{
	int k = 0;
	for (int j = 0; j < len; j++)
	{
		if (di[j] != word[j])
		{
			k++;
			if (k > 1) break;
		}
	}
	if (k < 2) return true;
	return false;
}

inline bool getDel(int len, char di[])
{
	int k = 0;
	for (int j = 0, w = 0; j < len; j++, w++)
	{
		if (di[w] != word[j])
		{
			k++;
			if (k > 1) break;
			j--;
		}
	}
	if (k < 2) return true;
	return false;
}

inline bool getIns(int len, char di[])
{
	int k = 0;
	for (int j = 0, w = 0; w < len-1; j++, w++)
	{
		if (di[w] != word[j])
		{
			k++;
			if (k > 1) break;
			w--;
		}
	}
	if (k < 2) return true;
	return false;
}

int main()
{
	strNode W;
	while (gets(W.str))
	{
		for (int i = 0; i < WORD_SIZE; i++)
		{
			dict[i].clear();
		}

		num = 0;
		int len = strlen(W.str);
		W.num = num++;
		dict[len].push_back(W);

		while (gets(W.str) && W.str[0] != '#')
		{
			len = strlen(W.str);
			W.num = num++;
			dict[len].push_back(W);
		}
out:
		while (gets(word) && word[0] != '#')
		{
			len = strlen(word);
			int N = (int)dict[len].size();
			for (int i = 0; i < N; i++)
			{
				if (!strcmp(word, dict[len][i].str))
				{
					printf("%s is correct\n", word);
					goto out;
				}
			}

			printf("%s:", word);
			res.clear();

			for (int i = 0; i < N; i++)
			{
				if (getReplacing(len, dict[len][i].str))
				{
					res.push_back(dict[len][i]);
				}
			}
			N = (int)dict[len-1].size();
			for (int i = 0; i < N; i++)
			{
				if (getIns(len, dict[len-1][i].str))
				{
					res.push_back(dict[len-1][i]);
				}
			}
			N = (int)dict[len+1].size();
			for (int i = 0; i < N; i++)
			{
				if (getDel(len, dict[len+1][i].str))
				{
					res.push_back(dict[len+1][i]);
				}
			}

			sort(res.begin(), res.end());
			for (int i = 0; i < (int)res.size(); i++)
			{
				printf(" %s", res[i].str);
			}
			putchar('\n');
		}
	}
	return 0;
}

POJ 1035 Spell Check 字符串处理

时间: 2024-07-31 08:26:02

POJ 1035 Spell Check 字符串处理的相关文章

[ACM] POJ 1035 Spell checker (单词查找,删除替换增加任何一个字母)

Spell checker Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18693   Accepted: 6844 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given word

POJ 1035 Spell checker (串)

题目大意: 问你后面输入的串能不能通过  加减一个字符,或者替换一个字符变成字典中的串. 思路分析: 直接模拟替换加减的过程. 比较两个串的长度.要相差为1 的时候才能进行模拟. 模拟的过程就是进行一个个的匹配. 发现失配的次数小于等于 1就可以输出. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <string> #i

POJ 1035 Spell checker

题目链接 http://poj.org/problem?id=1035 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24142   Accepted: 8794 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the cor

poj 1035 Spell checker(暴力判断)

题目链接:http://poj.org/problem?id=1035 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given words using a known dictionary of all correct words in all their f

POJ 1035 Spell checker (模拟)

题目链接 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given words using a known dictionary of all correct words in all their forms. If the word is absent in

poj 1035 纯正的字符串水

Spell checker Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 22673   Accepted: 8258 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given word

[ACM] POJ 1035 Spell checker (单词查找,删除替换添加不论什么一个字母)

Spell checker Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18693   Accepted: 6844 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given word

【POJ】1035 Spell checker

字典树. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <string> 7 using namespace std; 8 9 typedef struct Trie { 10 int in; 11 Trie *next[26]; 12 } Trie;

POJ 1035 代码+详细注释

Spell checker Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19319 Accepted: 7060 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given words us