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
【分析】串的模式匹配
题意:输入串A(模式串)和串B(主串),问串A在串B中出现了几次。
这里使用更高效的KMP算法实现,稍作修改即可实现串A出现次数的统计。
#include <stdio.h>
#include <string.h>
#define maxlenA 15
#define maxlenB 1005
int N;
//next数组-模式串部分匹配信息
//next[i]表示模式串的第i个字符与主串B中相应字符"失配"时,
//模式串A中需重新和主串B中该字符进行比较的字符位置
int next[maxlenA];
char A[maxlenA],B[maxlenB]; //A-模式串 B-主串
//求模式串A的部分匹配信息
void getNext(char *s,int *next)
{
int i,j,len;
i=0,j=-1;
len=strlen(s);
//规定next[0]=-1
next[i]=j;
//打表
while(i<len)
{
if(j==-1 || s[i]==s[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
//主串s 模式串t,统计模式串t在主串s中的出现次数
void KMP(char *s,char *t)
{
int i,j;
int lens,lent;//主串s和模式串t的长度
int ans; //模式串t在主串s中的出现次数
i=j=ans=0;
lens=strlen(s);
lent=strlen(t);
getNext(A,next);
while(i<lens && j<lent)
{
//j在模式串第一个字符前 或 主串和模式串对应位置字符相同,则向后考察
if(j==-1 || s[i]==t[j])
{
i++;
j++;
}
//否则,j回到重新和主串s匹配的位置
else
j=next[j];
//匹配成功,i不动,j从next[j]位置开始继续与主串s匹配
if(j>=lent)
{
ans++;
j=next[j];
}
}
printf("%d\n",ans);
}
int main()
{
int i;
scanf("%d",&N);
while(N--)
{
scanf("%s",A);
scanf("%s",B);
KMP(B,A);
}
return 0;
}