POJ 1035 Spell checker(串)

题目网址:http://poj.org/problem?id=1035

思路:

看到题目第一反应是用LCS ——最长公共子序列 来求解。因为给的字典比较多,最多有1w个,而LCS的算法时间复杂度是O(n*m),n,m分别对应两个字符串的长度。还要乘上字典的个数和所要匹配的单词数,不出意外地。。超时了。

后面就想到了暴力求解,直接枚举所有情况,先判断字符串长度差是否大于1,大于1的话直接进行下一个循环,否则再继续划分。(len对应字典词长度,l对应要查询的词长度)

假设匹配成功,只会有以下三种情况。

1.  len==l ,只可能是完美匹配,或是替换一个字母

2. len-1==l,查询的词要添加一个字母

3. len==l-1,查询的词要删去一个字母

 

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <cmath>
 5 using namespace std;
 6 char word[10005][20];
 7 char str[20];
 8 int main(){
 9     int cnt=-1;
10     while (gets(word[++cnt])!=NULL && word[cnt][0]!='#');
11     while (gets(str)!=NULL && str[0]!='#') {
12         vector<int>v;
13         int ok=0;
14         int l=(int)strlen(str);
15         printf("%s",str);
16         for (int i=0; i<cnt; i++) {
17             int len=(int)strlen(word[i]);
18             int cur=0,j=0,k=0;
19             if(fabs(len-l)>1)   continue;
20             if(len-l==0){//情况1
21                 while (str[j] && word[i][j] && cur<=1) {
22                     if (str[j]!=word[i][j]) cur++;
23                     j++;
24                 }
25                 if(cur==0){
26                     ok=1;
27                     printf(" is correct\n");
28                     break;
29                 }
30             }else if(len-l==1){//情况2
31                 while (str[k] && word[i][j]) {
32                     if(str[k]!=word[i][j]){
33                         cur++,j++;
34                         continue;
35                     }
36                     j++;k++;
37                 }
38             }else if(l-len==1){//情况3
39                 while (str[k] && word[i][j]) {
40                     if(str[k]!=word[i][j]){
41                         cur++,k++;
42                         continue;
43                     }
44                     j++;k++;
45                 }
46             }
47             if(cur<=1)  v.push_back(i);
48             
49         }
50         if(!ok){
51             printf(":");
52             for (int j=0; j<v.size(); j++) {
53                 printf(" ");
54                 printf("%s",word[v[j]]);
55             }
56             printf("\n");
57         }
58     }
59     return 0;
60 }

 

另附上用LCS做的超时版本。。有用LCS过的 欢迎讨论

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <string>
 5 #include <cmath>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 char word[10005][20];
10 char str[20];
11 int main(){
12     int cnt=-1;
13     while (gets(word[++cnt])!=NULL && word[cnt][0]!='#');
14     while (gets(str)!=NULL && str[0]!='#') {
15         vector<int>v;
16         int ok=0;
17         int l=(int)strlen(str);
18         printf("%s",str);
19         for (int i=0; i<cnt; i++) {
20             int lcs[20][20];
21             int Max=0;
22             int len=(int)strlen(word[i]);
23             if(fabs(len-l)>1)   continue;
24             memset(lcs, 0, sizeof(lcs));
25             for (int j=0; j<len; j++) {
26                 for (int k=0; k<l; k++) {
27                     if(word[i][j]==str[k])  lcs[j+1][k+1]=lcs[j][k]+1;
28                     else    lcs[j+1][k+1]=max(lcs[j+1][k], lcs[j][k+1]);
29                     Max=max(Max, lcs[j+1][k+1]);
30                 }
31             }
32             if(max(len,l)==Max){//完全匹配
33                 ok=1;
34                 printf(" is correct\n");
35                 break;
36             }else if(max(len,l)==Max+1){//增删改其中的一个情况
37                 if(len==Max || l==Max){//增删情况
38                     v.push_back(i);
39                 }else{
40                     int j=0;
41                     int cur=0;
42                     while (word[i][j] && str[j]) {
43                         if(word[i][j]==str[j])  cur++;
44                         j++;
45                     }
46                     if(cur==Max){//修改一个的情况
47                         v.push_back(i);
48                     }
49                 }
50             }
51         }
52         if(!ok){
53             printf(":");
54             for (int j=0; j<v.size(); j++) {
55                 printf(" ");
56                 printf("%s",word[v[j]]);
57             }
58             printf("\n");
59         }
60     }
61     return 0;
62 }

 

posted @ 2017-08-07 11:31  ventricle  阅读(164)  评论(0编辑  收藏  举报