对字符串hash的一些总结:

1,首先,我们在转化的时候,取底的时候一般是取131这些数,因为要避免不同的字符串对应相同的hash值这种情况的出现。如果卡精度的时候,我们可以采取双模数的方式尽量减少误差,(不过这种东西还是得看脸)。

2,在定义的时候,一般是为了定义成unsigned long long ,这个有一个好处,当爆int的时候,不会带上负号,就相当于对2的64次方进行取模了。

3.在进行hash的转换的时候,字符串对应的0位,hash值不是0,所以我们可以先将字符串往后移动一位再去赋值。

4,我们将一个整的字符串计算好hash值的时候,如果要取(l,r)这段区间的子串的hash值,可以采用以下公式。

ans =  hash[r] - hash[l-1]*ind[r-l+1];

A

单模数hash

题目链接:https://www.luogu.org/problemnew/show/P3370

具体思路:我们可以将字符串的每一个字符转换成数字,然后比较的时候,直接比较这个字符串对应的hash值就可以了。

AC代码:

 #include<iostream>
#include<stdio.h>
#include<iomanip>
#include<stack>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
# define ll long long
# define ull unsigned long long
const int base=;//一般比ascii码值大就可以了。
const int maxn = 1e4+;
char str[maxn];
ll a[maxn];
ull Hash(char a[])
{
int len=strlen(a);
ull sum=;
for(int i=; i<len; i++)
{
sum=sum*base+(ull)a[i];
}
return sum;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%s",str);
a[i]=Hash(str);
}
sort(a+,a+n+);
int ans=;
for(int i=; i<=n; i++)
{
if(a[i]!=a[i-])
ans++;
}
printf("%d\n",ans);
return ;
}

双模数hash

 #include<iostream>
#include<stdio.h>
#include<iomanip>
#include<stack>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
# define ll long long
# define ull unsigned long long
const int mod1=1e9+;
const int mod2=1e9+;
const int base=;
const int maxn = 1e4+;
char str[maxn];
struct node{
ull t1;
ull t2;
}q[maxn];
bool cmp(node s1,node s2){
return s1.t1<s2.t1;
}
ull hash1(char *a){
ull sum=;
int len=strlen(a);
for(int i=;i<len;i++){
sum=(sum*base+(ull)a[i])%mod1;
}
return sum;
}
ull hash2(char *a){
ull sum=;
int len=strlen(a);
for(int i=;i<len;i++){
sum=(sum*base+(ull)a[i])%mod2;
}
return sum;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%s",str);
q[i].t1=hash1(str);
q[i].t2=hash2(str);
}
sort(q+,q+n+,cmp);
int ans=;
for(int i=;i<=n;i++){
if(q[i].t1!=q[i-].t1||q[i].t2!=q[i-].t2)ans++;
}
printf("%d\n",ans);
return ;
}

B题:

题目链接:https://cn.vjudge.net/contest/276379#problem/J

题目大意:这本来是一道kmp的模板题,然后今下午打算用字符串hash做一下,结果一下午过去了,,,,

具体思路:和拓展kmp的方法相同,就是比较的时候直接比较子串的hash值就可以了。

AC代码:

 #include<iostream>
#include<stdio.h>
#include<iomanip>
#include<stack>
#include<algorithm>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
# define ll long long
# define ull unsigned long long
const int mod1=1e9+;
const int mod2=1e9+;
const ull base=;
const int maxn = 1e5+;
char str1[maxn],str2[maxn],com[];
ull hash1[maxn],hash2[maxn],ind[maxn];
map<char,char>vis;
void init()
{
ind[]=;
for(int i=; i<maxn; i++)
{
ind[i]=ind[i-]*base;
}
}
void hs1(char *a)
{
int len=strlen(a+);
hash1[]=;
for(int i=; i<=len; i++)
{
hash1[i]=hash1[i-]*base+(ull)a[i];
}
}
void hs2(char *a)
{
int len=strlen(a+);
hash2[]=;
for(int i=; i<=len; i++)
{
hash2[i]=hash2[i-]*base+(ull)a[i];
}
}
ull getsub1(int l,int r)
{
return hash1[r]-hash1[l-]*ind[r-l+];
}
ull getsub2(int l,int r)
{
return hash2[r]-hash2[l-]*ind[r-l+];
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",com);
scanf("%s",str1+);
for(int i=; i<; i++)
{
vis[com[i]]=char('a'+i);
}
int len=strlen(str1+);
for(int i=; i<=len; i++)
{
str2[i]=vis[str1[i]];
}
hs1(str1);
hs2(str2);
int ans=len;
for(int i=len; i<len+len; i++)
{
if(i&)continue;
int tmp=i/;
ull t1=getsub2(,len-tmp);
ull t2=getsub1(len-(len-tmp)+,len);
if(t1==t2)
{
ans=tmp;
break;
}
}
for(int i=; i<=ans; i++)
{
printf("%c",str1[i]);
}
for(int i=; i<=ans; i++)
{
printf("%c",str2[i]);
}
printf("\n");
}
return ;
}

字符串hash&&对字符串hash的理解的更多相关文章

  1. 转载:字符串hash总结(hash是一门优雅的暴力!)

    转载自:远航休息栈 字符串Hash总结 Hash是什么意思呢?某度翻译告诉我们: hash 英[hæʃ] 美[hæʃ]n. 剁碎的食物; #号; 蔬菜肉丁;vt. 把…弄乱; 切碎; 反复推敲; 搞糟 ...

  2. cdoj1092-韩爷的梦 (字符串hash)【hash】

    http://acm.uestc.edu.cn/#/problem/show/1092 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limi ...

  3. 字符串学习总结(Hash & Manacher & KMP)

    前言 终于开始学习新的东西了,总结一下字符串的一些知识. NO.1 字符串哈希(Hash) 定义 即将一个字符串转化成一个整数,并保证字符串不同,得到的哈希值不同,这样就可以用来判断一个该字串是否重复 ...

  4. BZOJ4598 [Sdoi2016]模式字符串 【点分治 + hash】

    题目 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m 的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多少对结点< ...

  5. 【基本算法入门-字符串哈希(Hash)】-C++

    字符串哈希入门 说得通俗一点,字符串哈希实质上就是把每个不同的字符串转成不同的整数. 为什么会有这样的需要呢?很明显,存储一个超长的字符串和存储一个超大但是能存的下的整数,后者所占的空间会少的多,但主 ...

  6. 841. 字符串哈希(hash)

    给定一个长度为n的字符串,再给定m个询问,每个询问包含四个整数l1,r1,l2,r2l1,r1,l2,r2,请你判断[l1,r1l1,r1]和[l2,r2l2,r2]这两个区间所包含的字符串子串是否完 ...

  7. Hash记录字符串

    Hash记录字符串模板: mod常常取1e9+7,base常常取299,,127等等等....有的题目会卡Hash,因为可能会有两个不同的Hash但却有相通的Hash值...这个时候可以用双Hash来 ...

  8. 安全的字符串拷贝strcpy_s的实现与理解

    在C标准库中提供了字符串拷贝函数strcpy,而微软则为为它提供了一个更安全的版本strcpy_s,其函数原型为 errno_t __cdecl strcpy_s( char* _Destinatio ...

  9. Ruby中的Hash(哈希),你可以理解为字典

    原文链接 以下代码在Ruby 2.5.1中编译通过 定义 myHash = Hash.new myHash1 = Hash["key1" => 100, "key2 ...

随机推荐

  1. C#中重写(override)和覆盖(new)的区别

    重写 用关键字 virtual 修饰的方法,叫虚方法.可以在子类中用override 声明同名的方法,这叫“重写”.相应的没有用virtual修饰的方法,我们叫它实方法.重写会改变父类方法的功能.看下 ...

  2. Java 软引用和弱引用

    软引用(SoftReference) 软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示.对于软引用关联着的对象,只有在内存不足的 ...

  3. jmeter发送json数据,报405、400错误解决方案

    1.405错误解决方案:添加HTTP信息头管理器(错误因数:发送格式未设置) 2.400错误解决方案:json文本格式有误(注意:换行.空格等)解决方案:对照json文本数据(错误因数:发送的json ...

  4. HNOI2013旅行

    一道欺负我智商的题... 本来想打单调队列优化dp的,结果看到算法标签就点了此题 洛谷题面 首先你要理解题意,蒟蒻理解了好久.它就是说,给你一个由1和-1组成的数列,让你分成m段,并让这m段区间和最大 ...

  5. 解题:洛谷4314 CPU监控

    题面 线段树·二重标记(什么鬼 用(a,b)标记表示先执行+a操作,然后对b取max,维护历史/当前最大值和历史/当前标记.然后我们发现区间加$x$就是$(x,-inf)$,区间赋$x$就是$(-in ...

  6. 解题:CQOI 2017 老C的任务

    题面 找到真正的KD-Tree题目了!然而出题人并不打算放KD-Tree过,只能O2了 // luogu-judger-enable-o2 #include<cstdio> #includ ...

  7. hdu 5852 :Intersection is not allowed! 行列式

    有K个棋子在一个大小为N×N的棋盘.一开始,它们都在棋盘的顶端,它们起始的位置是 (1,a1),(1,a2),...,(1,ak) ,它们的目的地是 (n,b1),(n,b2),...,(n,bk). ...

  8. python函数:基础函数调用整理

    声明:以下链接和描述据来自于网络,很多都是来自菜鸟教程 一.字符串 str python字符串格式化符号: %c 格式化字符及其ASCII码  %s 格式化字符串 %d 格式化整数 函数 描述 需要掌 ...

  9. cpplint

    Cpplint是一个Python脚本,作为一款开源免费的代码静态检测工具,Google也使用它作为自己的C++代码检测工具,也就是说,只要你的代码遵从Google C++代码规范,那么Cpplint将 ...

  10. springcloud之config 配置管理中心之配置属性加密解密

    1.为什么要加密解密? 为了维护项目的安全性. 2.配置加密解密的前提是什么? 要进行JCE下载,然后替换掉jdk的security文件: 下载链接:http://www.oracle.com/tec ...