描述
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.
查找字符串的子串个数。随意用哪种方式都行, STL的代码量很少,直接用string.find即可。KMP的效率高点,看测试数据了。
#include <stdio.h>
#include <string.h>
typedef unsigned int uint32_t;
int main(int argc, char** argv) {
uint32_t uNums = 0;
scanf("%d", &uNums),getchar();
while (uNums--) {
char strA[10] = { 0 };
char strB[1000] = { 0 };
scanf("%s", strA),getchar();
scanf("%s", strB),getchar();
uint32_t nLengthA = strlen(strA);
uint32_t nLengthB = strlen(strB);
int nMatchNum = 0;
for(int i = 0; i <= nLengthB - nLengthA; ++i) {
if (strncmp(strB + i, strA, nLengthA) == 0) {
nMatchNum++;
}
}
printf("%d\n", nMatchNum);
}
return 0;
}
上述代码的比较也是相当于指针回退,即使主串与模式串的前N个字符相同,也需要从新比较。 在最坏的情况下时间复杂度为O(n*m);
KMP算法本质就是求模式串中的前缀和后缀的最长的公共长度,即求解next数组。
比如主串:110100010101011 模式串:1010
1:前缀后缀为空集;共有长度0。
10:前缀1, 后缀0 ;共有长度0。
101:前缀:1, 10。 后缀:01, 1;共有长度1。
1010中 前缀:1, 10, 101 。 后缀: 010, 10, 0 。共有长度为2。
此题中存在主串中匹配的公共长度的子串重叠的情况,所以在进行KMP匹配的时候需要特别注意。比如上述例子。在主串第二次匹配模式串成功时返回位置7(从0开始),但是当前主串的下标已经到了10的位置。如果此时不回退,则少匹配一次模式串。