剪花布条 HDU - 2087 (KMP)
方法一:使用C++中string的find()函数
1 #include <iostream> 2 3 using namespace std; 4 5 int main() 6 { 7 string t, p; 8 while(true) 9 { 10 int ans = 0; 11 cin >> t; 12 if(t == "#") 13 break; 14 cin >> p; 15 16 int pos = t.find(p); 17 while(pos != string::npos) 18 { 19 ++ans; 20 pos = t.find(p, pos+p.length()); 21 } 22 23 cout << ans << endl; 24 } 25 26 27 return 0; 28 }
方法二:使用kmp算法
错误代码:
(1) 已经有库函数叫做next,所以next数组的命名不能再叫做next,否则会报next不明确的错误,这里改为nxt
(2) 不能写 while( i < t.length() && j < p.length() ),因为当j = -1时,因为p.length()是无符号整数,而-1是有符号整数,比较时会转换成无符号整数进行比较,则-1 > p.length(),这样就产生了错误
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int nxt[1010]; 7 8 void getNext(string p, int nxt[]) 9 { 10 nxt[0] = -1; 11 int i = 0, j = -1; 12 13 while (i < p.length()) 14 { 15 if (j == -1 || p[i] == p[j]) 16 { 17 ++i; 18 ++j; 19 nxt[i] = j; 20 } 21 else 22 { 23 j = nxt[j]; 24 } 25 } 26 } 27 28 int kmp(string t, string p) 29 { 30 int i = 0, j = 0; 31 32 // 不能写 while( i < t.length() && j < p.length() ), 33 // 因为当j = -1时,因为p.length()是无符号整数,则-1 > p.length(), 34 // 这样就产生了错误 35 while (i < t.length() && j < p.length()) 36 { 37 if (j == -1 || t[i] == p[j]) 38 { 39 ++i; 40 ++j; 41 } 42 else 43 { 44 j = nxt[j]; 45 } 46 } 47 48 if (j == p.length()) 49 return i - j; 50 else 51 return -1; 52 } 53 54 int main() 55 { 56 string t, p; 57 while (true) 58 { 59 int ans = 0; 60 cin >> t; 61 if (t == "#") 62 break; 63 cin >> p; 64 65 getNext(p, nxt); 66 int pos = kmp(t, p); 67 while (pos != -1) 68 { 69 ++ans; 70 t = t.substr(pos + p.length()); 71 pos = kmp(t, p); 72 } 73 74 cout << ans << endl; 75 } 76 77 78 return 0; 79 }
正确代码:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int nxt[1010]; 7 8 void getNext(string p, int nxt[]) 9 { 10 nxt[0] = -1; 11 int i = 0, j = -1; 12 13 int plen = p.length(); 14 while (i < plen) 15 { 16 if (j == -1 || p[i] == p[j]) 17 { 18 ++i; 19 ++j; 20 nxt[i] = j; 21 } 22 else 23 { 24 j = nxt[j]; 25 } 26 } 27 } 28 29 int kmp(string t, string p) 30 { 31 int i = 0, j = 0; 32 33 // 不能写 while( i < t.length() && j < p.length() ), 34 // 因为当j = -1时,因为p.length()是无符号整数,则-1 > p.length(), 35 // 这样就产生了错误 36 // 所以要事先用有符号整数保存 t.length()和p.length()的值 37 int tlen = t.length(); 38 int plen = p.length(); 39 while (i < tlen && j < plen) 40 { 41 if (j == -1 || t[i] == p[j]) 42 { 43 ++i; 44 ++j; 45 } 46 else 47 { 48 j = nxt[j]; 49 } 50 } 51 52 if (j == plen) 53 return i - j; 54 else 55 return -1; 56 } 57 58 int main() 59 { 60 string t, p; 61 while (true) 62 { 63 int ans = 0; 64 cin >> t; 65 if (t == "#") 66 break; 67 cin >> p; 68 69 getNext(p, nxt); 70 int pos = kmp(t, p); 71 while (pos != -1) 72 { 73 ++ans; 74 t = t.substr(pos + p.length()); 75 pos = kmp(t, p); 76 } 77 78 cout << ans << endl; 79 } 80 81 82 return 0; 83 }