字符串匹配--hash
思路:
先算出母串的hash值,再算出子串的hash值,利用差分的思想,计算出母串长度与子串长度相等的hash值,并进行判断,如果hash值相等,即可判断他们为相同的字符串,如果担心hash值冲突,即可加以一层判断来保证结果的准确性
时间复杂度O(n)
Code:
#include<iostream>
#include<vector>
#include<cmath>
#include<string.h>
#define ull unsigned long long//ull类型数据超过2^64自动取余
using namespace std;
const int X=13331;//进制数一般为13……31
const int N=1e6+5;
vector<ull> strhash;//动态定义母串hash数组
vector<ull> subhash;//动态定义子串hash数组
char str[N],sub[N];
ull x[N];//x[i]为X的i次方
int subl,strl;
void hash_code(char *s)//计算母串s的hash值
{
strhash[0]=s[0];
for(int i=1;i<strl;i++)
{
strhash[i]=strhash[i-1]*X+s[i];
}
}
void init()//初始化x数组
{
x[0]=1;
for(int i=1;i<N;i++)
x[i]=x[i-1]*X;
}
ull gethash(int left,int right)//获取字符串l到r区间的hash值
{
return left?strhash[right]-strhash[left-1]*x[right-left+1]:strhash[right];
}
int main()
{
cin>>str>>sub;
strl=strlen(str);
subl=strlen(sub);
getnxt();
getnxtv();
strhash.resize(strl);//开辟字符串长度的空间
subhash.resize(subl);//开辟空间
init();
hash_code(str);//计算母串str的hash值
subhash[0]=sub[0];
for(int i=1;i<subl;i++)
{
subhash[i]=subhash[i-1]*X+sub[i];//计算子串sub的hash值
}
for(int i=0;i<strl;i++)
{
if(gethash(i,i+subl-1)==subhash[subl-1]) cout<<i+1<<endl;//如果子串与母串的hash值相等,则证明子串与母串相等 ,并输出该子串在母串中的位置
}
return 0;
}

京公网安备 11010502036488号