【第十六课】哈希表(acwing-841字符串哈希 / 详解 / 优秀的文章推荐 / c++代码)

本文主要是介绍【第十六课】哈希表(acwing-841字符串哈希 / 详解 / 优秀的文章推荐 / c++代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

思想

代码如下

一些解释

1.基数P的选择

2.unsigned long long类型

可能需要看的文章博客


思想

咳咳,感觉这个刚开始第一遍接触的时候很抽象,,,还好网友们很强,有很通俗的解释办法hh。 

字符串的哈希核心思想是:我们把字符串当做一个P进制的数,有点像通过前缀和的思想得到两段字符串的哈希值,在判断两段字符串所映射的哈希值是否相同即可。

ha数组的每一位存的都是字符串的前 i 位映射之后的哈希值(这个哈希值的计算方式就是以P进制计算所得的数)。这里的P一般取131,13331 ,可以尽量避免冲突。(这个结论是在大量实践中得出的,我们平时使用直接记住就好。)

由于在进制数的运算中,通常需要求取次方,因此我们建立一个p数组,提前预处理出以P为基数的次方。方便后续的使用。

其实我们这里ha数组其实并不是哈希表,因为其元素表示的是哈希值,其下标表示的其实可以当作是字符串(因为下标是几表示的就是前缀到第几个字符的字符串)

也就是相比普通的哈希表下标表示哈希值,元素表示数据(回想一下840的散列表),也就是反过来了。

也就是说字符串哈希其实是运用到了哈希表的思想,其实实际的实现过程并不一定需要使用哈希表

哈希函数会将字符串映射到一个数字,这个过程并不需要哈希表。然而,如果想要存储和查找字符串,哈希表就可能会被用到,因为哈希表可以提供快速的查找速度

下面这张图也对解决字符串哈希的方式与我们所熟悉的十进制放在一起进行对照,相信可以理解哈。(这个英文字体好漂亮hh)

相信到这里,这种方法的思路应该是可以明白的.。

代码如下

#include<iostream>
using namespace std;const int N=1e5+10,P=131;
typedef unsigned long long ULL;int n,m;
char str[N];
ULL ha[N],p[N];//ha存储所有子串映射的哈希值  p数组存储 以 P 为进制数 的P的次方,方便加权求和
//ha数组的下标表示的就是前多少个字符  p数组的下标表示的就是对应多少次方ULL get(int l,int r)
{return ha[r]-ha[l-1]*p[r-l+1];
}
int main()
{scanf("%d%d%s",&n,&m,str+1);p[0]=1;for(int i=1;i<=n;i++){p[i]=p[i-1]*P;ha[i]=ha[i-1]*P+str[i];//加权求值}while(m--){int l1,r1,l2,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);if(get(l1,r1)==get(l2,r2))puts("Yes");else puts("No");}return 0;
}

一些解释

1.基数P的选择

选择P=131作为基数的原因与ASCII码表有关。在字符串哈希中,我们通常会将字符串中的每个字符转换为其对应的ASCII码,然后使用这些ASCII码来计算哈希值(这个理解哈)。ASCII码的范围是0到127,因此我们需要选择一个大于127的数作为基数,以确保不同的字符串能够映射到不同的哈希值。

通过下面的例子也很清楚。 

2.unsigned long long类型

求每个前缀字符串的哈希值的方法明白了之后,我们就要想,求的时候一直在乘次方,将会导致这个映射的数特别大,也就是我们将要存进ha数组中的数会很大,为了避免数据溢出,我们当然可以定义一个特别大的数据类型来避免溢出,只是再大也会有超限的时候,因此要完成取模工作,关于对谁取模,这里又是一个经验值,一般是2^64,而恰好unsigned long long有溢出自动取模的功能,因此我们就采用了这种定义数据类型的方式。

也就是说我们完整的求出哈希值的步骤就是:按照进制算出数字,再进行取模操作,这才完成了一个哈希值的运算

关于取模这里也有一个简化:就是我们定义unsigned long long类型的变量,它可以存储0到2^64−1之间的整数。当一个unsigned long long类型的变量的值超过2^64−1时,它会自动溢出,也就是说,它会自动对2^取余。

3.不能将一个字符串映射成0,要从1开始映射

从0开始映射的话会增加冲突概率。因此我们从1开始

4.str数组要从1开始,为的是方便前缀和计算。

可能需要看的文章博客

讲的很好的文章,这个平台好像是有很系统的算法的文章。非常推荐

字符串哈希

这个博主写了哈希专题,也很清晰。

哈希专题 

之前写的普通的哈希算法

【第十六课】哈希表上篇

可能需要回顾的kmp算法

kmp算法


字符串哈希写的汗流浃背(bushi),感觉不太好理解,把抽象的理解了之后发现还有很多细节需要琢磨。

有问题欢迎指出!一起加油!! 

这篇关于【第十六课】哈希表(acwing-841字符串哈希 / 详解 / 优秀的文章推荐 / c++代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/644495

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来