字符串哈希

引例

题目描述

给定一个字符串 A A A 和一个字符串 B B B,求 B B B A A A 中的出现次数。 A A A B B B 中的字符均为英语大写字母或小写字母。

A A A 中不同位置出现的 B B B 可重叠。

输入格式

输入共两行,分别是字符串 A A A 和字符串 B B B

输出格式

输出一个整数,表示 B B B A A A 中的出现次数。

样例输入

zyzyzyz
zyz

样例输出

3

数据范围与提示

1 ≤ A , B 1 \leq A, B 1A,B 的长度 ≤ 1 0 6 \leq 10 ^ 6 106 A A A B B B 仅包含大小写字母。

暴力求解思路

逐一枚举 A A A 中的位置 i i i 作为 B B B 的起点,检查是否可以匹配,时间复杂度为 O(n2),显然会超时。

一、进制

通过对各种进制的观察,我们不难发现:

  • 任意一个 R R R 进制的数,都可以看成是一个满足如下条件的字符串:
    • 每个位上都是 [ 0 , R − 1 ] [0, R-1] [0,R1] 之间的一个数字;
    • 两个字符串相等,当且仅当这两个字符串代表的 R R R 进制数相等。
  • 判断两个字符串相等,需要一层循环,是 O(n) 的,而判断两个数相等,是 O(1) 的。
  • 所有英文字母的取值范围都在 128 以内,因此,每个英文字母均可以看成是一个 R ( R > = 128 ) R(R>=128) R(R>=128) 进制数的基数值,任意一个字符串均可看作有一个或多个位的 R R R 进制数
    H ( " a b c d " ) = 97 ⋅ R 3 + 98 ⋅ R 2 + 99 ⋅ R + 100 H ( " a b " ) = 97 ⋅ R + 98 H ( " c d " ) = 99 ⋅ R + 100 = H ( a b c d ) − H ( a b ) ⋅ R 2 \begin{aligned} H("abcd") &= 97\cdot R^3+98\cdot R^2+99\cdot R+100 \\ H("ab") &= 97\cdot R+98 \\ H("cd") &= 99\cdot R+100=H(abcd)-H(ab)\cdot R^2 \end{aligned} H("abcd")H("ab")H("cd")=97R3+98R2+99R+100=97R+98=99R+100=H(abcd)H(ab)R2
    不难看出,在已知某个字符串的所有前缀的 R R R 进制数值的前提下,计算任意一个子串的 R R R 进制数值只需 O(1) 的时间(当然还需要预处理出 R i R^i Ri 的值)。

至此,对于上面的题目,我们可以:

  1. B B B 转为一个 R R R 进制数 h b hb hb,时间复杂度为 O(n)。
  2. 逐一枚举 A A A 中的位置 i i i,预处理出 A A A 的前 i i i 位构成的 R R R 进制数的数值 h [ i ] h[i] h[i],时间复杂度为 O(n)。
  3. 逐一枚举 A A A 中的位置 i i i,用 O(1) 的时间 A A A 中从第 i i i 个位开始的与 B B B 相同的一个字符串对应的 R R R 进制数 h a ha ha,检查是否满足 h b = = h a hb==ha hb==ha

按照这个思路,整个算法的时间复杂度就降到了 O(n),可以通过了。

但是等等,这里好像有一个问题:由于 R R R 是大于等于 128 的数, R i R^i Ri 很容易就会超出 i n t int int 甚至 l o n g l o n g long\ long long long 的取值范围,我们根本无法存储。而如果采用大整数来运算及存储,就得不偿失了。

那该怎么办呢?

我们遇到了一个取值范围远大于表示范围的对应问题,就如同关键字与位置下标的对应问题,要将取值范围非常大的一组数(字符串的 R R R 进制数值),尽量没有冲突地均匀存入一个空间有限的数组(基础变量类型的取值范围)中,这是标准的散列问题

二、散列

设计这种散列函数一定要简单且快,通常采用经典的“除留余数法”,为了减少冲突,我们需要做 2 件事情:

  • 要让余数的取值范围尽量大(采用最大的数据类型 unsigned long long,相当于模 264)。
  • R R R 选取一个大于 128 的素数,例如:131,13331 等等。

H ( " a b c d " ) = 97 × 13 1 3 + 98 × 13 1 2 + 99 × 131 + 100 = 218064827 + 1681778 + 12969 + 100 = 219746605 \begin{aligned} H("abcd") &= 97\times 131^3+98\times 131^2+99\times 131+100\\ &=218064827+1681778+12969+100\\ &=219746605 \end{aligned} H("abcd")=97×1313+98×1312+99×131+100=218064827+1681778+12969+100=219746605
那么,上面为什么没有去模 264 呢?因为 unsigned long long 本身恰好就是 64 位,它计算出来的结果本来就是只保留小于 264 的部分,这称作自然溢出

好啦!到此为止,我们就完成了真个算法设计,看看代码吧!

#include <iostream>
#include <cstring>
using namespace std;
using ULL = unsigned long long;
const int N = 1e6 + 7, P = 131;
ULL sum[N], sa, pw[N];
char s[N];
int main() {scanf("%s", s + 1);pw[0] = 1;int len = strlen(s + 1);for (int i = 1; s[i]; ++i) {sum[i] = sum[i-1] * P + s[i];pw[i] = pw[i-1] * P;}scanf("%s", s + 1);int lena = strlen(s + 1), ans = 0;for (int i = 1; s[i]; ++i)sa = sa * P + s[i];for (int i = 1; i+lena-1 <= len; ++i) {ULL d = sum[i+lena-1] - sum[i-1]*pw[lena];if (d == sa) ++ans;}printf("%d", ans);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/181073.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业微信,打造高效私域运营的重要工具!

随着数字时代的来临&#xff0c;私域运营已经成为了企业运营的重要环节。私域运营的核心在于人的运营&#xff0c;如何将目标用户牢牢地锁在自己的阵地上&#xff0c;并能够高效地运转起来&#xff0c;这是私域运营的关键所在。而企业微信&#xff0c;作为连接个人微信和企业微…

linux关于网络的一部分操作

目录 linux系统中一些简单的网络知识以及操作命令 查看ip命令 ping&#xff1a;检测与目标主机的连通性(现在很多服务器允许访问&#xff0c;但不允许ping发送的icmp包&#xff0c;防止探测) netstat&#xff1a;查看当前网络状态信息&#xff0c;包括服务及使用的端口 固定…

大地测量乙级资质申请条件

整理一期关于测绘资质大地测量乙级资质的申请要求 测绘资质是由测绘资质主管部门自然资源部制定的 想要了解标准、正规的申请条件&#xff0c;可以到当地省份的政务网搜索测绘资质办理相关标准&#xff08;例如下图&#xff09; 1、通用标准 http://gi.mnr.gov.cn/202106/P02…

在uniCloud中使用正则表达式进行文本匹配和处理的方法

1. 正则表达式基础 正则表达式是一种用来匹配字符串的模式。它由普通字符&#xff08;例如字符 a 到 z&#xff09;和特殊字符&#xff08;称为"元字符"&#xff09;组成。以下是一些基本的正则表达式示例&#xff1a; 匹配邮箱的正则表达式&#xff1a;/^[\w-](\.…

2023关键事件

情境/背景&#xff1a; SAP系统未提供配置BOM解析功能&#xff0c;多个业务部长多次开会强调系统没有配置BOM查询功能&#xff0c;严重影响供应链物料管理。目标/任务&#xff1a; 实现SAP系统中配置BOM解析功能自开发定制程序行动/举措&#xff1a; 花费大量业余时间&#xff…

Python与设计模式--模板模式

23种计模式之 前言 &#xff08;5&#xff09;单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、&#xff08;11&#xff09;策略模式、责任链模式、命令模式、中介者模…

java 鸿鹄云商 SAAS云产品概述 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城免费搭建

【SAAS云平台】打造全行业全渠道全场景的SaaS产品&#xff0c;为店铺经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营…

一秒开挂!纯 Python 开发 Web 应用

你好&#xff0c;我是 EarlGrey&#xff0c;喜欢翻译点东西&#xff0c;偶尔写写代码。 点击下方卡片关注我&#xff0c;一起向上进击&#xff0c;提升自我。后台回复关键词“电子书”&#xff0c;送你一份我收藏的电子书合集。 PyWebIO 是一个用于构建交互式 Web 应用程序的 P…

漫动作杂志漫动作杂志社漫动作编辑部2023年第10期目录

漫步艺海 钟日恒作品欣赏 (0001) 钟日恒 白建宁作品欣赏 (0003) 白建宁 史君仪作品欣赏 (0006) 史君仪 黄韬、时钺博作品欣赏 (0007) 黄韬;时钺博 刘合栋、方晓玲作品欣赏 (0008) 刘合栋;方晓玲 宗家禾作品欣赏 (0009) 宗家禾 漫游美术《漫动作》投稿&…

API网关

API网关的作用 下图显示了详细信息。 步骤 1 - 客户端向 API 网关发送 HTTP 请求。 步骤 2 - API 网关解析并验证 HTTP 请求中的属性。 步骤 3 - API 网关执行允许列表/拒绝列表检查。 步骤 4 - API 网关与身份提供商对话以进行身份​​验证和授权。 步骤 5 - 将速率限制规…

蓝桥杯第一天-----时间显示

文章目录 前言一、题目描述二、测试用例三、题目分析四、具体代码实现总结 前言 本章中将相信介绍蓝桥杯中关于时间显示的题目。 链接&#xff1a;https://www.lanqiao.cn/problems/1452/learning/ 一、题目描述 二、测试用例 三、题目分析 1.输入的时间为毫秒&#xff0c;毫…

大数据学习(26)-spark SQL核心总结

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

浅析linux中的信号

人们往往将信号称为“软件中断”&#xff0c;它提供了异步事件的处理机制&#xff0c;这些事件可以来自系统外部&#xff08;如用户按下ctrlc产生中断符&#xff09;&#xff0c;也可能来自程序或者内核内部的执行动作&#xff08;如进程除零操作&#xff09;。进程收到信号&am…

AcWing 2816. 判断子序列

文章目录 AcWing 2816. 判断子序列我的思路CODE 欣赏大神代码给点思考 AcWing 2816. 判断子序列 题目链接&#xff1a;https://www.acwing.com/activity/content/problem/content/2981/ 我的思路 直接硬套模版&#xff0c;把两个指针两层循环写上如果匹配&#xff0c;记录数组…

汽车内饰灯不亮问题修复

车内饰灯不亮问题修复 最近换后座阅读灯火光闪了一下&#xff0c;保险丝短路&#xff0c;导致车内所有灯光&#xff0c;包括前后座阅读灯、后备箱灯都不亮了。 因为是所有灯都不亮&#xff0c;所以排除灯泡问题&#xff0c;网上查了下大概率是保险丝烧了。于是查了自己更换保…

idea下载与安装,以及创建一个项目写HelloWorld

1.idea下载 Download IntelliJ IDEA – The Leading Java and Kotlin IDE (jetbrains.com) Ultimate为旗舰版&#xff0c;功能全面&#xff0c;插件丰富&#xff0c;按年收费。 Community为社区版&#xff0c;免费试用&#xff0c;功能相对而言不是很丰富&#xff0c;但是不影…

windows 映射 webdav 为本地磁盘

参考 https://docs.qnap.com/operating-system/qts/4.5.x/zh-cn/GUID-31D5B05F-F29E-4D61-9758-C8CF839C14FD.html WebDAV 允许用户访问和管理远程服务器上的文件。您可以通过 WebDAV 将 Windows 计算机上的共享文件夹装载为网络磁盘。 在 Windows 计算机上&#xff0c;打开“…

Linux系统---环境变量+内核进程调度队列(选学)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、环境变量 1.基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数&#xff0c;如: 我们在编写CI/…

Python 分解IP段获取所有IP(子网掩码)

需求 192.168.1.0/24,192.168.2.1-192.168.2.254,192.168.3.3 IP段格式已 "," 分割&#xff0c;获取所有IP 注意 1. 判断 IP 是否合规 2. 去除多余的字符&#xff0c;例如空格、换行符 3. 去重 代码 import re import ipaddressdef isIP(ip):p re.compile(^((…

JS调用Android原生相机设置

1、定义 private ValueCallback<Uri> mUploadMessage;public ValueCallback<Uri[]> uploadMessage;private Uri imageUri; 2、webview 设置 webView.setWebChromeClient(new WebChromeClient(){// For 3.0 Devices (Start)// onActivityResult attached before co…