博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【POJ3461】Oulipo(字符串Hash)
阅读量:5129 次
发布时间:2019-06-13

本文共 1229 字,大约阅读时间需要 4 分钟。

problem

  • 给定两个字符串s1,s2,求s1在s2中出现了多少次(可重叠)。
  • len(s1) < 1e4, len(s2) < 1e6。

solution

字符串Hash
介绍:

字符串匹配问题:寻找长为n的主串S中的匹配串T的位置或出现次数。

传统的做法:是枚举所有起始位置,再检查是否匹配。
字符串Hash:比较两个字符串的Hash是否相等。

具体:

如果我们用O(m)的时间计算长为m的字符串Hash值,则总的时间复杂度并没有变化。

所以我们采用滚动哈希的优化技巧。

  • 选择互质常数b,h,设字符串C=c1c2..cm。定义哈希函数H(C) = ((c1*b^m-1)+(c2*b^m-2)+..(cm*b^0))modh
  • 这样就可以递推计算字符串的Hash值。

codes

#include
#include
#include
using namespace std;typedef long long LL;const int maxn = 1e6+10, b = 31;char s1[maxn], s2[maxn];LL power[maxn], HA[maxn];int main(){ //预处理b^n power[0] = 1; for(int i = 1; i < maxn; i++) power[i] = power[i-1]*b; int T; cin>>T; while(T--){ scanf("%s%s",s1+1,s2+1); int n = strlen(s1+1), m = strlen(s2+1); //主串的Hash for(int i = 1; i <= m; i++) HA[i] = HA[i-1]*b+(LL)(s2[i]-'A'+1); //匹配串的Hash LL ha = 0; for(int i = 1; i <= n; i++) ha = ha*b+(LL)(s1[i]-'A'+1); //枚举起点为i,长为n的子串,O(1)计算Hash判断是否匹配 int ans = 0; for(int i = 0; i <= m-n; i++) if(ha == HA[i+n]-HA[i]*power[n])ans++; cout<
<<'\n'; } return 0;}

转载于:https://www.cnblogs.com/gwj1314/p/10200118.html

你可能感兴趣的文章
【原】小程序常见问题整理
查看>>
C# ITextSharp pdf 自动打印
查看>>
【Java】synchronized与lock的区别
查看>>
django高级应用(分页功能)
查看>>
【转】Linux之printf命令
查看>>
关于PHP会话:session和cookie
查看>>
STM32F10x_RTC秒中断
查看>>
display:none和visiblity:hidden区别
查看>>
C#double转化成字符串 保留小数位数, 不以科学计数法的形式出现。
查看>>
牛的障碍Cow Steeplechase
查看>>
Zookeeper选举算法原理
查看>>
3月29日AM
查看>>
利用IP地址查询接口来查询IP归属地
查看>>
HTML元素定义 ID,Class,Style的优先级
查看>>
构造者模式
查看>>
http和https的区别
查看>>
Hbuild在线云ios打包失败,提示BuildConfigure Failed 31013 App Store 图标 未找到 解决方法...
查看>>
找到树中指定id的所有父节点
查看>>
今天新开通了博客
查看>>
AS3优化性能笔记二
查看>>