【字符串算法1】 字符串Hash(优雅的暴力)

【字符串算法2】Manacher算法

【字符串算法3】KMP算法

这里将讲述  【字符串算法1】 字符串Hash

老版原文: RK哈希(Rabin_Karp 哈希) 仅仅具有参考价值

新版题目:【字符串算法1】 再谈字符串Hash(优雅的暴力)

概念

- 什么是字符串Hash?

- 就是把字符串映射成一个数字使每个字符串的映射结果不一样(把字符串有效的转化为数字

对字符进行映射

对一个字符进行唯一编码,如A-->1,B-->2,C-->3等等

一般不用ASCII码表来映射而是转化为相对小一点的值来映射

提示信息: (字符串内包含数字、大小写字母,大小写敏感)

写出val函数映射字符:

int val(char ch)
{
if (isdigit(ch)) return(ch-''+);
if (isupper(ch)) return(ch-'A'+);
if (islower(ch)) return(ch-'a'+);
}

对字符串进行映射

一般映射方法:hash[i]=(hash[i-1]*p+idx(s[i]))%mod (保险度:****)

hash[i]表示字符串的第i个前缀的hash值

Hash值的性质

①这样子,我们就可以记录下每个字符串对应的整数,当下一次出现了一个已经出现的字符串时,查询整数是否出现过,就可以知道 字符串是否重复出现。
②判断两个字符串是否一致,怎么办呢?直接用它们的hash值判断即可,若hash值一致,则认为字符串一致
若hash值不一致,则认为是不同的字符串。

例子

假设我们取p=13 ,mod=101
先把abc映射为一个整数
hash[0]=1,表示 a 映射为1
hash[1]=(hash[0]*p+idx(b))%mod=15,表示 ab 映射为 15
hash[2]=(hash[1]*p+idx(c))%mod=97
这样,我们就把 abc 映射为 97 这个数字了。

冲突:

假设mo数和基底e取值不当时就会发生冲突

就是两个字符串明明不同但映射出来的结果相同

举个极端的例子

e=0的情况 字符串"a"和字符串"b"映射出来的值都是0,就产生冲突

那么怎么调整才能使冲突概率小之又小呢?
- p取一个较大素数,mo取一个大素数。
习惯上,p取一个6到8位的素数即可,mo一般取大素数 1e9+7(1000000007)或
1e9+9(1000000009)【逃 19260817】

求出每个子串的hash值

注意到每一个hash[i]都是前缀和数字那么我们借用前缀和的思想,已知hash[r]和hash[l]求出Hash(l,r)表示前[l,r]子串的hash值

Hash[l]=(x1*el-1+x2*el-2+......+xl*e0)mod mo

Hash[l-1]=(x1*el-2+x2*el-3+......+xl-1*e0)mod mo

Hash[r]=(x1*er-1+x2*er-2+......+xr*e0)mod mo

Hash(l,r)=(xl*er-l+xl+1*er-l-1+......xr-1*e1+xr*e0)mod mo

Hash[l-1]*er-l+1=(x1*el-2+x2*el-3+......+xl-1*e0)*er-l+1mod mo=(x1*er-1+x2*er-2+......+xl-1*er-l+1)mod mo

Hash[r]-Hash[l-1]*er-l+1=((x1*er-1+x2*er-2+...xl-1*er-l+1+xl*er-l...+xr*e0)-(x1*er-1+x2*er-2+......+xl*er-l+1))mod mo =(xl*er-l+xl+1*er-l-1+......xr-1*e1+xr*e0)mod mo=Hash(l,r)

所以:Hash[r]-Hash[l-1]*er-l+1=Hash(l,r)

ll pow(int x,int n,int p)
{
if (n==) return ;
if (n==) return x%p;
ll t=t*t%p;
if (n%==) t=t*x%p;
return t;
}
ll Hash(int l,int r)
{
return ((hash[r]-hash[l-]*pow(e,r-l+,mo)%mo)%mo+mo)%mo;
}

其他hash方法

1. unsigned long long hash[N];
hash[i]=hash[i-1]*p(自动取模) (保险度***) 常数(几乎没有) (容易被卡)
2. hash[i]=(hash[i-1]*p+idx(s[i]))%mod (保险度****) 常数(有一点) (一般)
3. 双hash 
hash1[i]=(hash1[i-1]*p+idx(s[i]))%mod1
hash2[i]=(hash2[i-1]*p+idx(s[i]))%mod2
pair<hash1,hash2>表示一个字符串! (保险度*****) 常数(比较大)(孪生质数不可能被卡)

推荐 :hash[i]=(hash[i-1]*p+idx(s[i]))%mod (保险度****) 常数(有一点) (一般)

题目描述

如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。

输入输出格式

输入格式:

第一行包含一个整数N,为字符串的个数。

接下来N行每行包含一个字符串,为所提供的字符串。

输出格式:

输出包含一行,包含一个整数,为不同的字符串个数。

输入输出样例

输入样例#1: 复制

5
abc
aaaa
abc
abcc
12345
输出样例#1: 复制

4

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,Mi≈6,Mmax<=15;

对于70%的数据:N<=1000,Mi≈100,Mmax<=150

对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500

样例说明:

样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。

Tip: 感兴趣的话,你们可以先看一看以下三题:

BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的^_^

【字符串算法1】 再谈字符串Hash(优雅的暴力)的更多相关文章

  1. [VB.NET Tips]再谈字符串连接之内置池

    CLR自动维护一个称为"内置池"(暂存池)(intern pool)的表,在编译时此表包含程序中声明的每个唯一的字符串常量的单个实例,以及以编程方式创建的String类的任何唯一实 ...

  2. Python 再谈字符串

    字符串除了要用引号来创建之外,其他和元组一样,不能修改,如果要修改只能用切片或者拼接的方式. 其他的什么乱七八糟的运算符都一样 一些不同 capitalize()-将字符串的第一个字母大写 str1. ...

  3. 【字符串算法2】浅谈Manacher算法

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  字符串算法2:Manacher算法 问题:给出字符串S(限制见后)求出最 ...

  4. 【字符串算法3】浅谈KMP算法

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法3]KMP算法 Part1 理解KMP的精髓和思想 其实KM ...

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

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

  6. 浅谈字符串Hash

    浅谈字符串Hash 本篇随笔讲解Hash(散列表)的一个重要应用:字符串Hash. 关于Hash Hash是一种数据结构,叫做Hash表(哈希表),也叫散列表.关于Hash的实现,其实与离散化颇为类似 ...

  7. 解决AES算法CBC模式加密字符串后再解密出现乱码问题

    问题 在使用 AES CBC 模式加密字符串后,再进行解密,解密得到的字符串出现乱码情况,通常都是前几十个字节乱码: 复现 因为是使用部门 cgi AESEncryptUtil 库,找到问题后,在这里 ...

  8. 浅谈字符串哈希 By cellur925

    前言 蒟蒻最近在复习字符串算法...但正如之前所说,我OI太菜被关起来了,本蒟蒻只能从最简单的哈希入手了TAT.而别的dalao都在学习AC自动机/后缀数组等高到不知哪里去的算法qwq. 基本思想 映 ...

  9. [算法2-数组与字符串的查找与匹配] (.NET源码学习)

    [算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法)   2. 字符串查找(算法)   3. C#中的String(源码)   4. 特性Attribute 与内 ...

随机推荐

  1. Ubuntu系统上双节点部署OpenStack

    安装和部署双节点OpenStack 介绍: 1.宿主机:Win10操作系统 2.在VMware下创建两台虚拟机: devstack-controller:控制节点 + 网络节点 + 块存储节点 + 计 ...

  2. 同步IO和异步IO的区别

    首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO.非阻塞IO.IO服用 ...

  3. 网络对抗技术 2017-2018-2 20152515 Exp4 恶意代码分析

    1.实验后回答问题 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控. 答:- 我会使用sysmon工具来 ...

  4. 2017-2018-2 20155224『网络对抗技术』Exp5:MSF基础应用

    基础问题回答 用自己的话解释什么是exploit,payload,encode? exploit就相当于是载具,将真正要负责攻击的代码传送到靶机中,我觉得老师上课举的火箭和卫星的例子非常形象,火箭只是 ...

  5. [穷尽]ADO.NET连接字符串

    微软提供的四种数据库连接方式: System.Data.OleDb.OleDbConnection System.Data.SqlClient.SqlConnection System.Data.Od ...

  6. 软件测试 —— Bug

    [Bug规范] Bug标题中需包含Bug的具体位置并以[]标注 举例:[模块-子模块-页面]XXXXXXXXXXXX Bug标题尽量简明 做什么操作 + 出现什么结果,比如(点击提交按钮,出现卡顿现象 ...

  7. 设计模式 笔记 解释器模式 Interpreter

    //---------------------------15/04/26---------------------------- //Interpreter 解释器模式----类行为型模式 /* 1 ...

  8. 架构师修炼 II - 表达思维与驾驭方法论

    开篇之前我想先说说当年开发的那点事儿:大约10年前吧,我还是一个程序员的时候经常都是遇到这样的项目开发流程: 解决方案 :满足客户目的和投标用的一堆文档(不少还是互联网上抄的) ,是以Word为主的纯 ...

  9. .NET Core 开发之旅 (1. .NET Core R2安装教程及Hello示例)

    前言 前几天.NET Core发布了.NET Core 1.0.1 R2 预览版,之前想着有时间尝试下.NET Core.由于各种原因,就没有初试.刚好,前几天看到.NET Core发布新版本了,决定 ...

  10. React半科普文

    React半科普文 什么是React getting started 文件分离 Server端编译 定义一个组件 使用property 组件嵌套 组件更新 Virtual DOM react nati ...