洛谷P3370 && 字符串哈希讲解
字符串哈希
寻找长度为n的主串s中的的匹配串T(长度为m)出现的位置或者次数问题属于字符串匹配问题。
朴素(一般)的想法就是从一个字符串的头开始for循环查找,当查找的一个字符与匹配串首字符相同时,往后查找长度为匹配串长度的字符串并一一比对,如果都一样的话,那么答案就加一;
但是往往有些题数据复杂度不允许这么干,于是我们引入字符串哈希这种操作;
具体流程:
滚动哈希,是优化复杂度的核心;
对于一个字符串的哈希值,我们定义哈希函数为H(C)=(c1b^m-1=c2b^m-2....+cmb^0)mod h,
说明:C为一个字符串名称,它由c1c2c3...cm组成,也就是C=c1c2c3c4....cm,其中m为C的长度;
b和h为互质的两个数(b<h),
也就是我们可以把一个字符串看成一个b进制的数(把‘A’看成1,把‘B’看成2...),因为10进制数(such as1234)可以表示成为1*10^3+2*10^2+3*10^1+4,在这里把10换成b就是b进制数的表示方式;因为字符串哈希形成的数可能很大所以要对原数进行取模h。
很多神仙心中可能会有疑问:取模后即使是不同的字符串他们的哈希值也可能相等,那么不同的字符串会有可能得出相同的哈希值,这样答案不就出错了吗?
答案是有可能的。算法错误?!
但是我们可以将可能性降到几乎忽略不计!
因为 仔细想想,是取模运算使哈希拥有了这种可能,只有取到h和b的公倍数时,哈希值才会相等,
但是我们把最小公倍数搞的很大,不就取不到了吗?
那么首先b和h要满足互质,在相近大小下使公倍数尽可能大,然后有意识调高b和h的值,
如果分别去h=1e9+7,b=1e9+9的话,他们最小公倍数就为(1e9+7)*(1e9+9),哈希值相同概率为1/(1e9+7)*(1e9+9),小到没朋友;
(可惜还是有毒瘤小伙伴出毒瘤数据坑害蒟蒻们。。)
不管了。。反正算法就是这样;
在代码实现中,h不必专门取1e9+7后再进行手动缩小操作,只要利用unsigned无符号整形的自然溢出特性,即可实现;
ok!
安利一个关于scanf读入字符串的小知识:
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define b 97//97是个质数,你也可以取的更大!
using namespace std;
int n,a[],ans=;//ans初始值为1,因为后面在判断时会少一个
char s[];
inline long long hash(char s[]){
int lenc=strlen(s+);
unsigned long long sum[];
sum[]=;
for(int i=;i<=lenc;i++)
sum[i]=sum[i-]*b+(unsigned)(s[i]-'');//哈希值求法
return sum[lenc];
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s+);
a[i]=hash(s);//对于每一个字符串求哈希值
}
sort(a+,a++n);
for(int i=;i<=n;i++)
if(a[i]!=a[i-])ans++;
printf("%d",ans);
return ;
}
还有一个惨痛教训:
这是b开成7后碰到了那极小概率的惨痛经历。。。
而且测试点太大无法下载。。。
完结。。
洛谷P3370 && 字符串哈希讲解的更多相关文章
- 洛谷 P3370 字符串哈希 (模板)
<题目链接> <转载于 >>> > 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共 ...
- 洛谷 P3370 【模板】字符串哈希
洛谷 P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的 ...
- 洛谷P3370 【模板】字符串哈希
P3370 [模板]字符串哈希 143通过 483提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 看不出来,这题哪里是哈希了- 题目描述 如题,给定N个字符串(第i个 ...
- 洛谷—— P3370 【模板】字符串哈希
P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好 ...
- 洛谷 P3370 【模板】字符串哈希 (set||map||哈希||字典树(mle)
P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. #友情提醒:如果真的想好 ...
- 洛谷——P3370 【模板】字符串哈希
题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转 ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 洛谷 简单字符串 'P1055ISBN号码' 问题
题目描述如下: 知识点①:char数组与int型数字进行运算时,需要将 char[i]-'0' .比如 char c[5]; int i; for(i=0;i<5;i++) scanf(&quo ...
- 洛谷P1098 字符串的展开【字符串】【模拟】
题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或者“4-8”的字串,我们就把它当作一种简写,输出时,用连续递增的字母或数 ...
随机推荐
- SQL常见面试题(学生表_课程表_总表)
问题描述: 为管理岗位业务培训信息,建立3个表: S (S#,SN,SD,SA) S#,SN,SD,SA 分别代表学号.学员姓名.所属单位.学员年龄 C (C#,CN ) C#,CN 分别代表课程编号 ...
- 什么是maven?maven中的pom文件是做什么的?
Maven 是专门用于构建和管理Java相关项目的管理工具. 1.使用Maven管理的Java 项目都有着相同的项目结构 2.统一维护jar包 POM是项目对象模型(Project Object Mo ...
- 【神经网络与深度学习】Caffe Model Zoo许多训练好的caffemodel
Caffe Model Zoo 许多的研究者和工程师已经创建了Caffe模型,用于不同的任务,使用各种种类的框架和数据.这些模型被学习和应用到许多问题上,从简单的回归到大规模的视觉分类,到Siames ...
- 【Linux开发】linux设备驱动归纳总结(八):1.总线、设备和驱动
linux设备驱动归纳总结(八):1.总线.设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- Emgu 学习之HelloWorld
安装和配置 系统Win10,VS2013,下载Emgu安装包libemgucv-windesktop-3.4.3.3016 安装到了E:\OpenCV\emgucv-windesktop 3.4.3. ...
- [转帖]Docker常用命令总结
Docker常用命令总结 http://www.ha97.com/5546.html 发表于: Linux, 互联网, 虚拟化与云计算 | 作者: 博客教主 标签: docker,常用命令,总结 PS ...
- 【深入理解JVM】类加载器与双亲委派模型 (转)
出处: [深入理解JVM]类加载器与双亲委派模型 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过 ...
- 如何不用 transition 和 animation 也能做网页动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/BxbQJj 可交互视频教 ...
- Tensorflow常见函数case argmax equal
常用的函数: tf.argmax(input, axis=None, name=None, dimension=None) input:输入Tensor axis:0表示按列,1表示按行 name:名 ...
- 第四篇 jQuery中的事件与应用
4.1 事件中的冒泡现象,ready()方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...