当前位置: 首页 > news >正文

算法刷题笔记 字符串哈希(C++实现)

文章目录

    • 题目描述
    • 基本思路
    • 实现代码

题目描述

  • 给定一个长度为n的字符串,再给定m个询问,每个询问包含四个整数l1,r1,l2,r2
  • 请你判断[l1,r1][l2,r2]这两个区间所包含的字符串子串是否完全相同。
  • 字符串中只包含大小写英文字母和数字。

输入格式

  • 第一行包含整数nm,表示字符串长度和询问次数。
  • 第二行包含一个长度为n的字符串,字符串中只包含大小写英文字母和数字。
  • 接下来m行,每行包含四个整数l1,r1,l2,r2,表示一次询问所涉及的两个区间。
  • 注意,字符串的位置从1开始编号。

输出格式

  • 对于每个询问输出一个结果,如果两个字符串子串完全相同则输出Yes,否则输出No
  • 每个结果占一行。

数据范围

  • 1 ≤ n,m ≤ 10^5

基本思路

  • 字符串哈希是一种非常常用的哈希方式,很多与字符串有关的算法问题都可以通过字符串哈希得到快速解决。
  • 字符串哈希的方法被称为字符串前缀哈希法。在这种方法中,哈希表中下标为i的单元存储着字符串中前i个字符构成的子串对应的哈希值。我们可以把字符串视为一个P进制的数字(这里的P一般取13113331),不同的字符都转换为其对应的唯一的ASCII码。
  • 通过上面的方式,对于任意一个字符串,我们都可以将其转换为一个P进制的数字。这个数字一般都非常大,所以我们除了会使用最大的整型unsigned long long之外(这里使用无符号整型也可以起到溢出自动取模的作用,并且至少使用8个字节进行存储)会对该数据取模,模数为264次方。这样的取法使得发生哈希冲突的可能性最小。
  • 在字符串哈希中有两个注意事项:首先,我们不能将任意字符映射为数字0;其次,我们假设字符串哈希过程中都不会发生哈希冲突。
  • 在字符串哈希中,只需要对一个字符串构建好了哈希表,则可以求出其中任意一个子串的哈希值。当子串的左端点下标为L,右端点下标为R时,该子串对应的哈希值为:h[R]- h[L - 1] * p^(R-L+1),具体的证明过程略。

实现代码

#include <iostream>
using namespace std;// 分别表示字符串长度、询问次数和每一次的查询内容
int n, m;
int l1, r1, l2, r2;
// 分别表示字符串的长度上限和所采用的P值
const int N = 100010;
const int P = 131;
// 分别用于存储字符串、字符串对应的前缀哈希表以及P的幂次
char str[N];
unsigned long long hash_table[N], p_power[N];int main(void)
{// 输入部分,构建哈希表cin >> n >> m;p_power[0] = 1;for(int i = 1; i <= n; ++ i){cin >> str[i];hash_table[i] = hash_table[i - 1] * P + str[i];p_power[i] = P * p_power[i - 1];}// 查询部分for(int i = 0; i < m; ++ i){cin >> l1 >> r1 >> l2 >> r2;unsigned long long hash1 = hash_table[r1] - hash_table[l1 - 1] * p_power[r1 - l1 + 1];unsigned long long hash2 = hash_table[r2] - hash_table[l2 - 1] * p_power[r2 - l2 + 1];if(hash1 == hash2) cout << "Yes" << endl;else cout << "No" << endl;}return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【07】分布式事务解决方案
  • Spring Boot请求参数映射:@RequestBody、@RequestParam和@RequestPart的应用
  • 破解反爬虫策略 /_guard/auto.js(一) 原理
  • spring security新版本的爽点在哪里,DSL?
  • 【事件排查】网络问题排查H3C无线优化方案
  • Postcat使用全解析
  • 大龄程序员的出路在哪里?
  • 爬虫(二)——爬虫的伪装
  • WEB渗透之相关概念(笔记)
  • parallel 详细解析 Java 8 Stream API 中的 parallel 方法
  • R语言包AMORE安装报错问题以及RStudio与Rtools环境配置
  • 【SASS/SCSS(一)】选择器
  • 高校如何拥抱国产化OS?中南民族大学信息化应用实践
  • iOS 左滑返回事件的控制
  • leetcode热题100.分割等和子集(动态规划)
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 11111111
  • Angularjs之国际化
  • canvas绘制圆角头像
  • CSS相对定位
  • C学习-枚举(九)
  • download使用浅析
  • FineReport中如何实现自动滚屏效果
  • httpie使用详解
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Python socket服务器端、客户端传送信息
  • SQL 难点解决:记录的引用
  • vuex 学习笔记 01
  • Zepto.js源码学习之二
  • 如何编写一个可升级的智能合约
  • 实习面试笔记
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • ​linux启动进程的方式
  • #ifdef 的技巧用法
  • $().each和$.each的区别
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (编译到47%失败)to be deleted
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (四)React组件、useState、组件样式
  • (轉)JSON.stringify 语法实例讲解
  • .bat批处理出现中文乱码的情况
  • .Net中的设计模式——Factory Method模式
  • .vimrc 配置项
  • @ResponseBody
  • @vueup/vue-quill使用quill-better-table报moduleClass is not a constructor
  • [ Socket学习 ] 第一章:网络基础知识
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [\u4e00-\u9fa5] //匹配中文字符
  • []sim300 GPRS数据收发程序