KMP算法,字符串哈希,最长公共子序列LCS,最长回文子序列LPS,AC自动机详细及模板

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++
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值