题目
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自动机等算法。
代码
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 }