http://www.cnblogs.com/zyf0163/p/4806951.html

hash函数对大家来说不陌生吧 ?

而这次我们就用hash函数来实现字符串匹配。

首先我们会想一下二进制数。

对于任意一个二进制数,我们将它化为10进制的数的方法如下(以二进制数1101101为例):

hash用的也是一样的原理,为每一个前缀(也可以后缀,笔者习惯1 base,所以喜欢用前缀来计算,Hash[i] = Hash[i - 1] * x + s[i](其中1 < i <= n,Hash[0] = 0)。

一般地,

而对于l - r区间的hash值,则为:

但是如果n很大呢?那样不是会溢出了吗?

因此我们把hash值储存在unsigned long long里面, 那样溢出时,会自动取余2的64次方,but这样可能会使2个不同串的哈希值相同,但这样的概率极低(不排除你的运气不好)。

因此我们可以通过Hash值来比较两个字符串是否相等。

给出多项式hash的处理:

typedef unsigned long long ull;
const int N = + ;
const ull base = ;
char s[N];
ull hash[N]; void init(){//处理hash值
p[] = ;
hash[] = ;
int n = strlen(s + );
for(int i = ; i <=; i ++)p[i] =p[i-] * base;
for(int i = ; i <= n; i ++)hash[i] = hash[i - ] * base + (s[i] - 'a');
} ull get(int l, int r, ull g[]){//取出g里l - r里面的字符串的hash值
return g[r] - g[l - ] * p[r - l + ];
}
我们来看到题目吧:传送门

题目大意:

是有一份文件,前面是密文,后面是原文,但那个人接到这个文件后不知道中间从哪里开始是原文,所以你要帮忙还原一下,如果后面原文比密文少,你就将它补全, 第一行是密文转换格式,例如第二个样例表示将q翻译成a,w翻译成b。

思路:

我们只要先把密文都翻译成明文,然后去比较原来的字符串的后缀和翻译之后的字符串前缀的最长匹配长度就行(注:最长匹配的长度不能超过原长的一半)

hash水题(附AC代码):

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
const int N = + ;
const ull base = ;
ull Hash1[N], Hash2[N], p[N]; char s[N], t[], r[N]; int T; int c[]; void init(){
p[] = ;
for(int i = ; i <=; i ++)p[i] =p[i-] * base;
} ull get(int l, int r, ull g[]){
return g[r] - g[l - ]*p[r - l + ];
} void work(){
for(int i = ; i < ; i ++) c[t[i] - 'a'] = i;
//puts(r+1);
int n = strlen(s + );
Hash1[] = Hash2[] = ;
for(int i = ; i <= n; i ++){
Hash1[i] = Hash1[i - ] * base + (s[i] - 'a');
Hash2[i] = Hash2[i - ] * base + (c[s[i] - 'a']);
}
int ans = n;
for(int i = n; i < n * ; i ++){
if(i & ) continue;
int tmp = i / ;
int len =n - tmp;
ull s1 = get(, len, Hash2);
ull s2 = get(n - len + , n, Hash1);
if(s1 == s2){
ans = tmp;
break;
}
//printf("%llu %llu\n", s1, s2);
}
//printf("ans = %d\n", ans);
for(int i = ; i <= ans; i ++)printf("%c", s[i]);
for(int i = ; i <= ans; i ++)printf("%c", c[s[i]-'a'] + 'a');
puts("");
} int main(){
scanf("%d", &T);
init();
while(T--){
scanf("%s%s", t, s + );
work();
}
return ;
}
 

字符串hash算法的更多相关文章

  1. 记录几个经典的字符串hash算法

    记录几个经典的字符串hash算法,方便以后查看: 推荐一篇文章: http://www.partow.net/programming/hashfunctions/# (1)暴雪字符串hash #inc ...

  2. 字符串Hash算法比较

    基本概念所谓完美哈希函数,就是指没有冲突的哈希函数,即对任意的 key1 != key2 有h(key1) != h(key2).设定义域为X,值域为Y, n=|X|,m=|Y|,那么肯定有m> ...

  3. HDU 1880 魔咒词典 (字符串hash)

    <题目链接> 题目大意: 就是每个字符串有一个配套的对应字符串,询问的时候,无论输出其中的哪一个字符串,输出另一个,如果不存在这个字符串,直接输出"what?". 解题 ...

  4. 字符串hash与字典树

    title: 字符串hash与字典树 date: 2018-08-01 22:05:29 tags: acm 算法 字符串 概述 这篇主要是关于字符串里的 字符串hash 和 字符串字典树,,两个都是 ...

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

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

  6. hadoop Partiton中的字符串Hash函数改进

    最近的MapReduce端的Partition根据map生成的Key来进行哈希,导致哈希出来的Reduce端处理任务数量非常不均匀,有些Reduce端处理的数据量非常小(几分钟就执行完成,而最后的pa ...

  7. 转载:字符串HASH

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

  8. 89.hash算法实现CSDN密码处理

    初始化,数据的行数,hash链表结构体,存储头结点 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdl ...

  9. 字符串Hash学习笔记

    [toc] # 以下内容作废,太多错误了,等我有时间重写 说一下什么是Hash,说白了就是把一大坨字符用一些神奇的数来表示,可以说是把字符加密了. 简单一点就是一个像函数一样的东西,你放进去一个值,它 ...

随机推荐

  1. gnome3.X添加开机启动项

    背景:升级gnome后发现gnome-session-properties不见了,想把sslocal随机启动遇到了麻烦... 特别说明:此为图形桌面开机启动项,因此只有通过图形桌面登陆用户后才能启动. ...

  2. linux -a 到 -z 的意义

    shell if判断中常用的也就是绿色部分,尾部部分越看越不懂.从百度文库转载. [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则 ...

  3. DotSpatial 删除图层要素

    //添加图层后,定义图层,并获取图层 //遍历要素,并进行删除 FeatureSet fs = null; fs = (FeatureSet) map1.Layers[0].DataSet; //要素 ...

  4. [转载]va_start和va_end使用详解

    va_start和va_end使用详解 原文地址:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html 本文主要介绍va_s ...

  5. 关于freeCAD

    FreeCAD界面 FreeCAD的功能目的是成为一个3D CAD 建模工具.她的开发完全遵循 Open Source (GPL & LGPL License)协议. FreeCAD的目标直指 ...

  6. bigdecimal 保留小数位

    public class test1_format { public static void main(String[] args) { BigDecimal decimal = new BigDec ...

  7. loadrunner四大部分

    loadrunner主要分一下四部分 1.VuGen  主要进行录制,回放,参数化,脚本修改,可以对脚本进行recording options,General options,runtime opti ...

  8. Android添加代码检查权限

    1,首先创建一个项目,然后创建一个类,hello.java public class hello { public static final String PERMISSION_SAY_HELLO = ...

  9. Android深度探索--HAL与驱动开发----第七章读书笔记

    首先创建led驱动的设备文件,可以使用cdev_init,register_chrdev_region,cdev_add等建立主设备号的设备文件.步骤如下: 1使用cdev_init初始化cdev 2 ...

  10. c# 远程连接ORACLE数据库

    使用该方法,只需要传入几个必要的参数就可以进行数据库的远程连接测试了,连接成功返回TRUE,失败返回false. 说明: 第一个参数表示你在数据库中的用户,具有可以登录权限的 第二个参数表示用户的密码 ...