字符串Hash学习笔记
[toc]
# 以下内容作废,太多错误了,等我有时间重写
说一下什么是Hash,说白了就是把一大坨字符用一些神奇的数来表示,可以说是把字符加密了.
简单一点就是一个像函数一样的东西,你放进去一个值,它给你输出来一个值。输出的值就是Hash值。一般Hash值会比原来的值更好储存(更小)或比较。
字符串hash的灵魂就是尽量让不同的字符串对应唯一的hsah的值 .而要实现这一效果就要选对方法否则就咕咕咕了
举个栗子:
如果我们的加密方法是把字符的ascal加起来,那就咕咕咕了.
比如:
ababa
babaa
加起来是一样的,咕咕咕....
所以应该怎么hash?
用一种名为“BKDR Hash”的字符串Hash算法:
它的主要思路是选取恰当的进制,可以把字符串中的字符看成一个大数字中的每一位数字,不过比较字符串和比较大数字的复杂度并没有什么区别(高精数的比较也是O(n)O(n)的),但只要把它对一个数取模,然后认为取模后的结果相等原数就相等,那么就可以在一定的错误率的基础上O(1)O(1)进行判断了。
那么我们选择什么进制比较好?
首先不要把任意字符对应到数字0,比如假如把a对应到数字0,那么将不能只从Hash结果上区分ab和b(虽然可以额外判断字符串长度,但不把任意字符对应到数字0更加省事且没有任何副作用),一般而言,把a-z对应到数字1-26比较合适。
关于进制的选择实际上非常自由,大于所有字符对应的数字的最大值,不要含有模数的质因子(那还模什么),比如一个字符集是a到z的题目,选择27、233、19260817都是可以的。
模数的选择(尽量还是要选择质数):
绝大多数情况下,不要选择一个109109级别的数,因为这样随机数据都会有Hash冲突,根据生日悖论,随便找上109−−−√109个串就有大概率出现至少一对Hash 值相等的串
最稳妥的办法是选择两个109109级别的质数,只有模这两个数都相等才判断相等,但常数略大,代码相对难写,目前暂时没有办法卡掉这种写法(除了卡时间让它超时)
如果能背过或在考场上找出一个10181018级别的质数(Miller-Rabin),也相对靠谱,主要用于前一种担心会超时,后一种担心被卡。
偷懒的写法就是直接使用unsigned long long,不手动进行取模,它溢出时会自动对264
送上一道模板题:
P3370 【模板】字符串哈希
题目描述
如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。
输入输出格式
输入格式:
第一行包含一个整数N,为字符串的个数。
接下来N行每行包含一个字符串,为所提供的字符串。
输出格式:
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,Mi≈6,Mmax<=15;
对于70%的数据:N<=1000,Mi≈100,Mmax<=150
对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
#define ll long long int
#define mod 1000000007
using namespace std;
const long long int maxn=;
const int minn=-;
long long base=;
long long a[];
char s[];
int n,ans=;
long long hash(char s[]) {
int len=strlen(s);
long long ans=;
for (int i=; i<len; i++)
ans=ans*base+(long long )s[i];
return ans%maxn;
}
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\n",ans);
}
送上取膜数对答案的影响:
.
改了一下mod为0x3f3f3f就
所以hsah最的最后一步:烧香拜佛保AC!
字符串Hash学习笔记的更多相关文章
- Hash学习笔记
啊啊啊啊,这篇博客估计是我最早的边写边学的博客了,先忌一忌. 本文章借鉴与一本通提高篇,但因为是个人的学习笔记,因此写上原创. 目录 谁TM边写边学还写这玩意? 后面又加了 Hash Hash表 更多 ...
- 字符串HASH 学习总结 && 模板
一.字符串HASH模板 取自挑战程序设计竞赛(第2版) </pre><pre code_snippet_id="446698" snippet_file_nam ...
- 字符串Hash/树Hash学习笔记
哈希 Tags:字符串 作业部落 评论地址 一.概述 百度百科: 散列表(Hash table/哈希表),是根据关键码值(Key value)而直接进行访问的数据结构. 哈希表常用于比较两个字符串是否 ...
- ruby的hash学习笔记例: 将字符串文本中的单词存放在map中
text = 'The rain in Spain falls mainly in the plain.'first = Hash.new []second = Hash.new {|hash,key ...
- 【KMP】【字符串】KMP字符串匹配算法 学习笔记
一.简介 KMP是由Knuth.Morris和Prat发明的字符串匹配算法,它的时间复杂度是均摊\(O(n+m)\).其实用Hash也可以做到线性,只不过Hash存在极其微小的难以避免的冲突. ...
- KMP字符串模式匹配学习笔记
KMP算法实验 1.编程计算模式串(子串)的next值.2.利用KMP算法在主串中找到模式串的位置. 参考代码:---------int getNexlVal( char * s, int j)// ...
- OI字符串 简单学习笔记
持续更新qwq KMP 其实是MP啦qwq 就是先自己匹配自己得到状态图,然后再在上面进行模式串的匹配. nxt数组返回的是以该节点结尾的,最长的,在前面出现过的,不相交的,字符串的最靠右的,末位位置 ...
- Python字符串(Python学习笔记02)
字符串 Python 3 中的字符串可以使用双引号或单引号标示,如果字符串出现引号,则可以使用 \ 来去除引号标示字符串的作用. 几种字符串的表示方法: str1 = "hello" ...
- python字符串方法学习笔记
# 一.字符串大小写转换# 字符串首字符大写print("hello world".capitalize())# 将字符串变为标题print("hello WORLD&q ...
随机推荐
- Authentication using SASL/Kerberos
Prerequisites KerberosIf your organization is already using a Kerberos server (for example, by using ...
- 一款比较强大的jquery表格插件Datatables
Datatables是一款jquery表格插件.它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能. 链接:http://www.datatables.club/ 本人无聊时发现的一款用 ...
- (转载) js 单引号替换成双引号,双引号替换成单引号 操作
引言:刚开始用js遇到不少问题,表示看不懂,为什么替换单引号需要/g,现在知道/g是正则中的匹配全部 原文:http://blog.csdn.net/joyhen/article/details/43 ...
- 给基于对话框的MFC程序添加状态栏并实时显示时间
转载自丝雪儿 1.首先在string table 里添加两个字串,ID分别为IDS_INDICATOR_MESSAGE and IDS_INDICATOR_TIME 2.在你的 dlg.h 类里面加个 ...
- Python - 实现矩阵转置
有个朋友提出了一个问题:手头上现在有一个二维列表,比如[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],现在要把该二维列表变成为[[1, 4, 7, 10 ...
- Vue学习之组件切换及父子组件小结(八)
一.组件切换: 1.v-if与v-else方式: <!DOCTYPE html> <html lang="en"> <head> <met ...
- MYSQL使用mysqldump导出表的部分数据
MySQLdump是MySQL自带的导出数据工具,通常我们用它来导出MySQL中,但是有时候我们需要导出MySQL数据库中某个表的部分数据,这时该怎么办呢? mysqldump命令中带有一个 --wh ...
- input限制输入
input 只能输入数字.字母.汉字等 1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace( ...
- Django之auth认证
Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的 ...
- Tensorflow简单实践系列(二):张量
在上一节中,我们安装 TensorFlow 并运行了最简单的应用,这节我们熟悉 TensorFlow 中的张量. 张量是 TensorFlow 的核心数据类型.数学里面也有张量的概念,但是 Tenso ...