字符串hash&&对字符串hash的理解
对字符串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的理解的更多相关文章
- 转载:字符串hash总结(hash是一门优雅的暴力!)
转载自:远航休息栈 字符串Hash总结 Hash是什么意思呢?某度翻译告诉我们: hash 英[hæʃ] 美[hæʃ]n. 剁碎的食物; #号; 蔬菜肉丁;vt. 把…弄乱; 切碎; 反复推敲; 搞糟 ...
- cdoj1092-韩爷的梦 (字符串hash)【hash】
http://acm.uestc.edu.cn/#/problem/show/1092 韩爷的梦 Time Limit: 200/100MS (Java/Others) Memory Limi ...
- 字符串学习总结(Hash & Manacher & KMP)
前言 终于开始学习新的东西了,总结一下字符串的一些知识. NO.1 字符串哈希(Hash) 定义 即将一个字符串转化成一个整数,并保证字符串不同,得到的哈希值不同,这样就可以用来判断一个该字串是否重复 ...
- BZOJ4598 [Sdoi2016]模式字符串 【点分治 + hash】
题目 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m 的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多少对结点< ...
- 【基本算法入门-字符串哈希(Hash)】-C++
字符串哈希入门 说得通俗一点,字符串哈希实质上就是把每个不同的字符串转成不同的整数. 为什么会有这样的需要呢?很明显,存储一个超长的字符串和存储一个超大但是能存的下的整数,后者所占的空间会少的多,但主 ...
- 841. 字符串哈希(hash)
给定一个长度为n的字符串,再给定m个询问,每个询问包含四个整数l1,r1,l2,r2l1,r1,l2,r2,请你判断[l1,r1l1,r1]和[l2,r2l2,r2]这两个区间所包含的字符串子串是否完 ...
- Hash记录字符串
Hash记录字符串模板: mod常常取1e9+7,base常常取299,,127等等等....有的题目会卡Hash,因为可能会有两个不同的Hash但却有相通的Hash值...这个时候可以用双Hash来 ...
- 安全的字符串拷贝strcpy_s的实现与理解
在C标准库中提供了字符串拷贝函数strcpy,而微软则为为它提供了一个更安全的版本strcpy_s,其函数原型为 errno_t __cdecl strcpy_s( char* _Destinatio ...
- Ruby中的Hash(哈希),你可以理解为字典
原文链接 以下代码在Ruby 2.5.1中编译通过 定义 myHash = Hash.new myHash1 = Hash["key1" => 100, "key2 ...
随机推荐
- Ld, -rpath, -rpath-link
http://blog.csdn.net/xph23/article/details/38157491
- C 语法中static 和inline联合使用
最近在学习阶段,翻阅代码.发现有一个用法比较让我奇怪,就上网查了一下 ? 1 static inline void somefunction(void); 这里是举例说明,这行代码是放在.h文件中的. ...
- 解题:POI 2007 Tourist Attractions
题面 事实上这份代码在洛谷过不去,因为好像要用到一些压缩空间的技巧,我并不想(hui)写(捂脸) 先预处理$1$到$k+1$这些点之间相互的最短路和它们到终点的最短路,并记录下每个点能够转移到时的状态 ...
- Webpack 配置示例
Webpack 作为前端构建工具,对于大型网站开发,大大提升了开发效率.要使用webpack需要先安装webpack工具: 先来看一个最简单的命令 $ webpack main.js bundle.j ...
- C++:(拷贝,继承,智能指针)练习
#include <iostream> #include <string> #include <memory> #include <functional> ...
- svn断开链接后,重新share提交代码报错
前言:svn怎样断开链接并清除干净请查看此地址-->android studio中断开SVN连接,并彻底清理项目中的.svn文件 1.每次把项目重新关联到新的svn地址上,我都抓狂一样的烦躁,因 ...
- (一)C的编译,printf,规范化
(一)编译的具体过程: 以前一直觉得,C代码的具体实现过程就是把几个.c文件编译成.o文件,然后链接在一起就可以了.可是最近在看C Prime Plus查漏补缺基础知识的过程中发现,这里的链接其实链接 ...
- python的函数介绍 位置参数 关键字参数 默认参数 参数组 *args **kwargs
1.数学意义的函数与python中的函数 数学意义的函数 y = 2*3+1 x =3 y =7 x是自变量,y是因变量 2.python中定义函数的方法 一个函数往往都是为了完成一个特定的功能而存在 ...
- GetVersionEx 正确获取windows10版本
vs2008直接将下面xml保存成文件添加到资源文件 vc的话insert-->Resource-->Custom-->输入24,ok-->id改为1-->把下面内容保存 ...
- OpenStack 认证服务 KeyStone连接和用户管理(四)
连接keystone两种方式: 一种使用命令 一种使用环境变量 1.通过环境变量方式连接keystone(适合在初始化场景使用) 配置认证令牌环境变量 export OS_TOKEN=07081849 ...