题目:有多个case,每个case中有一个案例库,求给定字符串是否是案例库中的子串,若是输出个数。
输入:第一行,输出案例库中字符串的个数N,下面N行数为每一个字符串;给定字符串的个数为M,下面M行为给定字符串
例子:
3 //case1案例库 aaa aaa baa 2 //给定字符串 aa ba 1 //case2 案例库 a 1 //给定字符串 a 输出 3 //aa是案例库1中三个字符串的子串,个数为3 1 //ba是案例库1中第三个字符串的子串,故个数为1 1 //a是案例库2中的字串,个数为1
解法:用给定的字符串轮流的和案例库中字符比较,看是否是其子串,若是,则个数加1。
1 #include<iostream> 2 #include<string> 3 #include<vector> 4 5 using namespace std; 6 7 bool isMatch(const string &dict, const string &example); 8 vector<int> getNext(const string &needle, int m, vector<int> next); 9 10 int main() 11 { 12 while (cin) //此处是否正确? 13 { 14 int N; 15 cin >> N; 16 vector<string> dict(N, ""); 17 for (int i = 0;i<N;i++) 18 { 19 cin >> dict[i]; 20 } 21 22 int M; 23 cin >> M; 24 vector<string> example(M, ""); 25 for (int i = 0;i<M;i++) 26 { 27 cin >> example[i]; 28 } 29 30 for (int i = 0;i<M;i++) 31 { 32 int count = 0; 33 for (int j = 0;j<N;j++) 34 { 35 if (isMatch(dict[j], example[i])) 36 { 37 count++; 38 } 39 } 40 cout << count << endl; //输出 41 } 42 } 43 return 0; 44 } 45 46 //KMP匹配算法 47 bool isMatch(const string &dict, const string &example) 48 { 49 int n = dict.size(), i = 0; 50 int m = example.size(), j = 0; 51 52 if (m>n) return false; 53 if (n == 0 || m == 0) return true; 54 55 vector<int> next(m); 56 next = getNext(example, m, next); 57 58 while (j<m&&i<n) 59 { 60 if ((0>j) || dict[i] == example[j]) 61 { 62 i++; 63 j++; 64 } 65 else 66 { 67 j = next[j]; 68 } 69 } 70 return j == m ? true : false; 71 } 72 73 vector<int> getNext(const string &needle, int m, vector<int> next) 74 { 75 int t = -1; 76 next[0] = -1; 77 int j = 0; 78 while (j<m - 1) 79 { 80 if (0>t || needle[j] == needle[t]) 81 { 82 j++; 83 t++; 84 next[j] = (needle[j] != needle[t] ? t : next[t]); 85 } 86 else 87 t = next[t]; 88 } 89 return next; 90 }
做题失败的原因,主要在对多个case之间的交替处理上,还有对输出时考虑失误,不一定要先保存输出结果,然后再输出。好几次笔试都是在输入输出上存在问题,在这方面要引起警觉。