KMP算法
KMP能在线性时间内判定字符串A【1~N】是否为字符串V【1 ~M】的子串,并求出A在B中各次出现的位置.
next数组求法:
#include<bits/stdc++.h>
using namespace std;
int Next[1000],f[1000];
char a[100],b[100];
int n,m;
void get_kmp_next(){
Next[1]=0;
for(int i=2,j=0;i<=n;i++){
while(j>0&&a[i]!=a[j+1])j=Next[j];
if(a[i]==a[j+1])j++;
Next[i]=j;
}
// Next数组:
// printf("Next:\n");
// for(int i=1;i<=n;i++)printf("%d ",Next[i]);
// printf("\nend\n");
}
void get_kmp_f(){
for(int i=1,j=0;i<=m;i++){
while(j>0&&(j==n||b[i]!=a[j+1]))j=Next[j];
if(b[i]==a[j+1])j++;
f[i]=j;
if(j==n){
printf("ans->%d ",i);}//此时就是A在B中的某一次出现
}
}
int main(){
cin>>m>>n>>b+1>>a+1;
get_kmp_next();
get_kmp_f();
}
/*
20 5
aabbaaccbbccaabaaaa
ccbbc
*/
字符串Hash
主要原理:将一个字符串转化为一个数字.
由于整数的储存大小有限,所以要%mod,但是%mod的话有可能会造成哈希冲突,所以可以改进为将一个字符串转换为两个整数.
点击进入题目链接
#include<iostream>
#include<cstring>
using namespace std;
#define pll pair<long long,long long>
#define ll long long
const int N = 3e6 + 10;
ll mod1 = 402653189;//素数1
ll mod2 = 201326611;//素数2
ll pw[N],hw[N];//预处理的数组 1,2
ll hash1[N];//储存母串s哈希值的数组1
ll hash2[N];//储存母串s哈希值的数组2
ll tmp1[N],tmp2[N];//储存子串t哈希值的数组1,2
char s[N],t[N];//母串s,子串t
int n;
//查询两个字符串的哈希值是不是相等
pll Hash(int l,int r,ll hash1[],ll hash2[]){
return pll((hash1[r] - hash1[l - 1] * hw[r - l + 1] % mod1 + mod1) % mod1,(hash2[r] - hash2[l - 1] * pw[r - l + 1] % mod2 + mod2) % mod2);
}
//把字符串转换为俩个哈希值数组
void func1(ll hash1[],ll hash2[],char *str,int l,int r){
for(int j = l;j <= r;j++