题目

http://poj.org/problem?id=1035


题意

字典匹配,单词表共有1e4个单词,单词长度小于15,需要对最多50个单词进行匹配。在匹配时,如果直接匹配可以找到待匹配串,则直接输出正确信息,否则输出所有满足以下条件的单词:

1. 待匹配串删除任意一个字符后可以匹配的

2. 单词删除任意一个字符后可以匹配的

3. 把待匹配串中某个字符改为单词对应字符后可以匹配的

思路
由于单词表容量较小,直接匹配可以直接使用strcmp进行。若直接匹配不成功,那么需要对每个单词进行再次比较,

对每个单词,仅有以下三种可能,设待匹配串长度为patlen,单词长度为wlen,

1. patlen > wlen:只需找到待匹配串中第一个与单词不同的字符,删除后再看剩下的是否全等即可。

2. patlen < wlen:类似第一种情况,只需找到单词中第一个与待匹配串不同的字符,删除后再看剩下的是否全等即可。

3. patlen == wlen:若能够通过替换匹配,那么两个字符串最多只能有一个字符不同。

感想
做这道题时为了节约思考时间使用了最朴素的比较方法,如果需要提升自己的能力不应该使用这种算法,可以使用dp,kmp,trie树,ac自动机等算法。

代码

POJ 1035 Spell checker 字符串 难度:0_iosPOJ 1035 Spell checker 字符串 难度:0_i++_02
 1 #include <cstdio>
 2 #include <map>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <string>
 7 #include <vector>
 8 #include <iostream>
 9 #include <assert.h>
10 #include <sstream>
11 #include <cctype>
12 #include <queue>
13 #include <stack>
14 #include <map>
15 #include <iterator>
16 using namespace std;
17 typedef long long ll;
18 typedef pair<int,int> P;
19 typedef unsigned long long ull;
20 typedef long long ll;
21 typedef long double ld;
22 
23 const int wordlen = 16;
24 const int maxn = 1e4 + 4;
25 
26 char words[maxn][wordlen];
27 char pat[wordlen];
28 
29 int n;
30 int wlens[maxn];
31 
32 bool canMatch(char * pat, char * word, int patlen, int wlen){
33     if(abs(wlen - patlen) > 1)return false;
34     if(wlen < patlen){
35         swap(pat, word);
36         swap(wlen, patlen);
37     }
38     if(wlen == patlen){
39         int num = 0;
40         for(int i = 0;i < patlen;i++){
41             if(word[i] != pat[i])num++;
42         }
43         return num <= 1;
44     }else{
45         for(int i = 0, j = 0;i < wlen;i++, j++){
46             if(word[i] != pat[j]){
47                 if(i == j)j--;
48                 else return false;
49             }
50         }
51         return true;
52     }
53 }
54 
55 void solve()
56 {
57     n = 0;
58     while(scanf("%s", words[n]) == 1 && (words[n][0] != '#' || words[n][1] != 0)) {
59         wlens[n] = strlen(words[n]);
60         n++;
61     }
62     while(scanf("%s", pat) == 1 && (pat[0] != '#' || pat[1] != 0))
63     {
64         bool correct = false;
65         for(int i = 0; i < n; i++)
66         {
67             if(strcmp(pat, words[i]) == 0)
68             {
69                 printf("%s is correct\n", pat);
70                 correct = true;
71                 break;
72             }
73         }
74         if(!correct)
75         {
76             int patlen = strlen(pat);
77             printf("%s:", pat);
78             for(int i = 0; i < n; i++)
79             {
80                 if(canMatch(pat, words[i], patlen, wlens[i]))
81                 {
82                     printf(" %s",words[i]);
83                 }
84             }
85             puts("");
86         }
87     }
88 }
89 int main(){
90     freopen("input.txt", "r", stdin);
91     solve();
92     return 0;
93 }
View Code