nyoj 题目5 Binary String Matching

Binary String Matching

时间限制:3000 ms  |  内存限制:65535 KB
难度:3
 
描述
Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For example, the text string B is ‘1001110110’ while the pattern string A is ‘11’, you should output 3, because the pattern A appeared at the posit
 
输入
The first line consist only one integer N, indicates N cases follows. In each case, there are two lines, the first line gives the string A, length (A) <= 10, and the second line gives the string B, length (B) <= 1000. And it is guaranteed that B is always longer than A.
输出
For each case, output a single line consist a single integer, tells how many times do B appears as a substring of A.
样例输入
3
11
1001110110
101
110010010010001
1010
110100010101011 
样例输出
3
0
3 

此题第一感觉就是用KMP算法,代码如下
 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 char a[12];
 5 char b[1002];
 6 int next[12];
 7 
 8 void getNext() {
 9     next[0] = -1;
10     int len = strlen(a);
11     int i = 0,j = -1;
12     while(i < len) {
13         if(j == -1 || a[i] == a[j]) {
14             i++,j++;
15             next[i] = j;
16         }
17         else {
18             j = next[j];
19         }
20     }
21 }
22 
23 int calCnt() {
24     int at = 0;
25     int bt = 0;
26     int ans = 0;
27     int lena = strlen(a);
28     int lenb = strlen(b);
29     while(bt < lenb) {
30         if(at == -1 || a[at] == b[bt]) {
31             at++;
32             bt++;
33             if(at == lena) {
34                 ans++;
35                 at = next[lena];
36             }
37             continue;
38         }
39         if(a[at] != b[bt]) {
40             at = next[at];
41         }
42 
43     }
44     return ans;
45 }
46 
47 int main(int argc, char const *argv[])
48 {
49     int n;
50     while(scanf("%d",&n) != EOF) {
51         while(n--) {
52             scanf("%s",a);
53             scanf("%s",b);
54             getNext();
55             int ans = calCnt();
56             printf("%d
", ans);
57         }
58     }
59     return 0;
60 }

此算法第一要求出next数组。而求next数组的过程本身也是一个自己和自己匹配的过程。此处用i不断前进,j不断返回,用作匹配。

计数时是新的匹配过程。和求next数组的过程神似。

若求nextval数组可能会更快些,代码如下

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 char a[12];
 5 char b[1002];
 6 int nextval[12];
 7 
 8 void getnextval() {
 9     nextval[0] = -1;
10     int len = strlen(a);
11     int i = 0,j = -1;
12     while(i < len) {
13         if(j == -1 || a[i] == a[j]) {
14             i++,j++;
15             if(i < len && a[i] == a[j]) {
16                 nextval[i] = nextval[j];
17             }
18             else {
19                 nextval[i] = j;
20             }
21             
22         }
23         else {
24             j = nextval[j];
25         }
26     }
27 }
28 
29 int calCnt() {
30     int at = 0;
31     int bt = 0;
32     int ans = 0;
33     int lena = strlen(a);
34     int lenb = strlen(b);
35     while(bt < lenb) {
36         if(at == -1 || a[at] == b[bt]) {
37             at++;
38             bt++;
39             if(at == lena) {
40                 ans++;
41                 at = nextval[lena];
42             }
43             continue;
44         }
45         if(a[at] != b[bt]) {
46             at = nextval[at];
47         }
48 
49     }
50     return ans;
51 }
52 
53 int main(int argc, char const *argv[])
54 {
55     int n;
56     while(scanf("%d",&n) != EOF) {
57         while(n--) {
58             scanf("%s",a);
59             scanf("%s",b);
60             getnextval();
61             int ans = calCnt();
62             printf("%d
", ans);
63         }
64     }
65     return 0;
66 }

要注意15行的条件。但实际运行好像并没有更快。

今天偶然发现nyoj可以查看优秀的代码,这一点简直完爆其他oj,看到这样一种非常取巧的办法

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int main(int argc, char const *argv[])
 6 {
 7     string s1,s2;
 8     int n;
 9     cin >> n;
10     
11     while(n--) {
12         cin >> s1;
13         cin >> s2;
14         size_t  m = s2.find(s1,0);
15         int ans = 0;
16         while(m != string::npos) {
17             ans++;
18             m = s2.find(s1,m+1);
19         }
20         cout << ans << endl;
21     }    
22     
23     return 0;
24 }
原文地址:https://www.cnblogs.com/jasonJie/p/6084501.html