对字符串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. TortoiseSVN使用svn+ssh协议连接服务器时重复提示输入密码

    当使用svn+ssh协议连接svn服务器时,ssh会提示请求认证,由于不是svn客户端程序来完成ssh的认证,所以不会缓存密码. 而svn客户端通常会建立多个版本库的连接,当密码没有缓存的时候,就会重 ...

  2. PGM学习之六 从有向无环图(DAG)到贝叶斯网络(Bayesian Networks)

    本文的目的是记录一些在学习贝叶斯网络(Bayesian Networks)过程中遇到的基本问题.主要包括有向无环图(DAG),I-Maps,分解(Factorization),有向分割(d-Separ ...

  3. BZOJ2800 [Poi2012]Leveling Ground 【扩展欧几里得 + 三分 + 堆】

    题目链接 BZOJ2800 题解 区间加极难操作,差分之后可转化为两点一加一减 那么现在问题就将每个点暂时独立开来 先判定每个点是否被\((A,B)\)整除,否则无解 之后我们先将\(A,B\)化为互 ...

  4. JS的关键字this

    1.关于this this关键字是JavaScript中最复杂的机制之一.它是一个很特别的关键字,被自动定义在所有函数的作用域中. 1.1 为什么要用this? this提供了一种更优雅的方式来隐式地 ...

  5. Android Studio多Module使用 aar 依赖包 丢包解决

    FAQ: AAR打包引用丢包问题, jar, aar, dependency 嵌套层级依赖的丢失 问: aar包中,如何包含第三方依赖库? 如果直接作为module 依赖是没有问题的,但是如果打包成a ...

  6. servlet与tomcat的关系

    1.4   Tomcat简介 学习Servlet技术,首先需要有一个Servlet运行环境,也就是需要有一个Servlet容器,本书采用的是Tomcat. Tomcat是一个免费的开放源代码的Serv ...

  7. python学习(24) 使用Xpath解析并抓取美女图片

    Xpath最初用来处理XML解析,同样适用于HTML文档处理.相比正则表达式更方便一些 Xpath基本规则 nodename 表示选取nodename 节点的所有子节点 / 表示当前节点的直接子节点 ...

  8. GO_04:GO语言基础条件、跳转、Array和Slice

    1. 判断语句if 1. 条件表达式没有括号(这点其他语言转过来的需要注意) 2. 支持一个初始化表达式(可以是并行方式,即:a, b, c := 1, 2, 3) 3. 左大括号必须和条件语句或 e ...

  9. Digia公司投资qt

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  10. KVM管理概述

    一.使用QEMU管理虚拟机 1.KVM指南 https://activedoc.opensuse.org/book/opensuse-virtualization-with-kvm/part-iii- ...