题目描述
知识点
字符串匹配,也就是KMP算法!
实现
码前思考
- 这道题的出题人给予我们宽容,所以暴力也是可以解的;
- 这道题目的标准解法应该是
KMP
,即时间复杂度为 ,空间复杂度为 。
代码实现
#include "bits/stdc++.h"
using namespace std;
//设置最长的长度为256
const int maxn = 1100;
//输入
char s[maxn];
char t[maxn];
//设置dp数组
int dp[maxn][256];
int T;
int main(){
scanf("%d",&T);
while(T--){
//读入输入数据
scanf("%s",s);
scanf("%s",t);
int n = strlen(s);
int m = strlen(t);
//用于计数有多少次匹配
int cnt = 0;
//首先进行初始化
fill(dp[0],dp[0]+maxn*256,0);
//表示在0状态下读入第一个字符转换到状态1
dp[0][t[0]] = 1;
//影子状态为0
int x = 0;
//原始的构建dp数组的情况
for(int j=1;j<m;j++){
for(int c=0;c<256;c++){
if(t[j] == c){
dp[j][c] = j+1;
}else{
dp[j][c] = dp[x][c];
}
}
x = dp[x][t[j]];
}
//注意这里m也要设置,因为我们要求子串的数量
for(int c=0;c<256;c++){
dp[m][c] = dp[x][c];
}
//下面进行匹配,KMP是不会回头的
int j=0;
for(int i=0;i<n;i++){
j = dp[j][s[i]];
if(j == m){ //到达了完全匹配状态,那么进行计数
cnt++;
}
}
printf("%d\n",cnt);
}
return 0;
}
码后反思
-
这里与传统的
KMP
不同的地方就是要记录匹配子串的数量。例如:ababa aba
我们在匹配成功之后,要直接回退到影子状态
X
。所以我们进行的是直接赋值,因为最后的那个状态也没有啥可以读入的字符了,处理如下:for(int c=0;c<256;c++){ dp[m][c] = dp[x][c]; }