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 = 100000 + 5;
const ull base = 163;
char s[N];
ull hash[N]; void init(){//处理hash值
p[0] = 1;
hash[0] = 0;
int n = strlen(s + 1);
for(int i = 1; i <=100000; i ++)p[i] =p[i-1] * base;
for(int i = 1; i <= n; i ++)hash[i] = hash[i - 1] * base + (s[i] - 'a');
} ull get(int l, int r, ull g[]){//取出g里l - r里面的字符串的hash值
return g[r] - g[l - 1] * p[r - l + 1];
}

我们来看到题目吧:传送门

题目大意:

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

思路:

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

hash水题(附AC代码):

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

  

字符串匹配(hash算法)的更多相关文章

  1. 字符串匹配KMP算法详解

    1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...

  2. 字符串匹配Boyer-Moore算法:文本编辑器中的查找功能是如何实现的?---这应该讲的最容易懂的文章了!

    关于字符串匹配算法有很多,之前我有讲过一篇 KMP 匹配算法:图解字符串匹配 KMP 算法,不懂 kmp 的建议看下,写的还不错,这个算法虽然很牛逼,但在实际中用的并不是特别多.至于选择哪一种字符串匹 ...

  3. 通用高效字符串匹配--Sunday算法

    字符串匹配(查找)算法是一类重要的字符串算法(String Algorithm).有两个字符串, 长度为m的haystack(查找串)和长度为n的needle(模式串), 它们构造自同一个有限的字母表 ...

  4. 字符串匹配--Karp-Rabin算法

    主要特征 1.使用hash函数 2.预处理阶段时间复杂度O(m),常量空间 3.查找阶段时间复杂度O(mn) 4.期望运行时间:O(n+m) 本文地址:http://www.cnblogs.com/a ...

  5. 字符串匹配常见算法(BF,RK,KMP,BM,Sunday)

    今日了解了一下字符串匹配的各种方法. 并对sundaysearch算法实现并且单元. 字符串匹配算法,是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目.此算法通常输入为原字符串(strin ...

  6. 字符串匹配&Rabin-Karp算法讲解

    问题描述: Rabin-Karp的预处理时间是O(m),匹配时间O( ( n - m + 1 ) m )既然与朴素算法的匹配时间一样,而且还多了一些预处理时间,那为什么我们还要学习这个算法呢?虽然Ra ...

  7. 字符串匹配KMP算法

    1. 字符串匹配的KMP算法 2. KMP算法详解 3. 从头到尾彻底理解KMP

  8. 字符串匹配--kmp算法原理整理

    kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...

  9. 算法——字符串匹配Rabin-Karp算法

    前言 Rabin-Karp字符串匹配算法和前面介绍的<朴素字符串匹配算法>类似,也是相应每一个字符进行比較.不同的是Rabin-Karp採用了把字符进行预处理,也就是对每一个字符进行相应进 ...

随机推荐

  1. 使用iText库创建PDF文件

    前言 译文连接:http://howtodoinjava.com/apache-commons/create-pdf-files-in-java-itext-tutorial/ 对于excel文件的读 ...

  2. sed实例精解--例说sed完整版

    原文地址:sed实例精解--例说sed完整版 作者:xiaozhenggang 最近在学习shell,怕学了后面忘了前面的就把学习和实验的过程记录下来了.这里是关于sed的,前面有三四篇分开的,现在都 ...

  3. MySQL 优化之 Linux系统层面调优

    MySQL 一般运行于Linux系统中.对于MySQL的调优一般分为Linux操作系统层面的调优和MySQL层面的调优(当然还有架构层面.业务层面.应用程序层面的调优).操作系统主要是管理和分配硬件资 ...

  4. SQL Server求解最近多少销售记录的销售额占比总销售额的指定比例

    看园中SQL Server大V潇潇隐者的博文,发现一边文就是描述了如标题描述的问题.   具体的问题描述我通过潇潇隐者的博文的截图来阐释: 注意:如果以上截取有所侵权,也请作者告知,再次感谢.   当 ...

  5. my_strcat()

    char* my_strcat(char* S1,const char* S2){ //严格符合strcat()的接口形式,需要的S1空间是两个字符串空间总和-1. int i=0,j=0; whil ...

  6. jQuery 3.0 的变化

    时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1. ...

  7. C# 为私有方法添加单元测试(反射)

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: ...

  8. git错误:Target branch can't be blank

    一.问题描述 遇到一个问题:Target branch can't be blank 因为问题再没有重现,所以拿一张网上的图: 情况是,比如a是项目的owner,有一个项目a/Project. b从a ...

  9. [转]教你一招 - 如何给nopcommerce增加新闻类别模块

    本文转自:http://www.nopchina.net/post/nopchina-teach-newscategory.html nopcommerce的新闻模块一直都没有新闻类别,但是很多情况下 ...

  10. 我懒蛋又回来了!-PDO

    hi 好几天了吧,脚伤都有一周了的.玩乐的这么久才发觉,对于年轻人,或者更具体的,对我而言,受伤最难受的不是受伤瞬间的身痛,不是随之而来的心理负担,不是独自一人远在他乡的孤独无助之感:最伤的是斗志,是 ...