c++字符串哈希

字符串哈希是一种将字符串映射为整数的算法。哈希函数将字符串映射到一个固定大小的整数,这个整数通常称为哈希值或哈希码。哈希函数应具有以下特征:

  1. 一致性:相同的字符串应该总是映射到相同的哈希值上。

  2. 散列性:不同的字符串应该映射到不同的哈希值上。

  3. 高效性:计算哈希值的算法应该是高效的。

今天我们用哈希来求一下字符串匹配的问题

先看问题

给定一个长度为 nn 的字符串,再给定 mm 个询问,每个询问包含四个整数 l1,r1,l2,r2l1,r1,l2,r2,请你判断 [l1,r1][l1,r1] 和 [l2,r2][l2,r2] 这两个区间所包含的字符串子串是否完全相同。

字符串中只包含大小写英文字母和数字。

输入格式
第一行包含整数 n 和 m,表示字符串长度和询问次数。

第二行包含一个长度为 n 的字符串,字符串中只包含大小写英文字母和数字。

接下来 m 行,每行包含四个整数 l1,r1,l2,r2,表示一次询问所涉及的两个区间。

注意,字符串的位置从 11 开始编号。

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

每个结果占一行。

数据范围
1≤n,m≤10^5

方法一:

遇到字符串匹配的方式,通常我们要想到KMP算法,个人认为KMP算法比较适合两个字符串来匹配,如果是一个字符串的话,就比较麻烦

方法二:

字符串哈希:
那什么是字符串哈希呢?

我们想要求一个字符串中的两段是不是相等,我们可以把该字符串的每一段都变为一个特殊的数字,然后直接匹配就行,预处理之后匹配的时间复杂度就是o(1)的,那我们现在讲一下如何预处理

之前我们将字符串的每一段都变为一个特殊的数字是怎么意思呢?怎么变呢?

1、我们让字符串的第一个字符乘以一个特殊的数字,然后再加上本身的值,再让前面两个字符乘以特殊的数字的平方,再加上前面两个本身的数值

2、为什么要这样的,因为我们在用哈希的时候,就是相当于把某一个数映射在另外一个区间上,为了最大限度避免冲突,所以要乘以一个特殊数字,那这个特殊数字既可以是131,也可以是13331(这是经验所得,就不证明了)

具体代码如下

#include<iostream>

using namespace std;

typedef unsigned long long ULL;

const int N=100010,P=131;//注意这里是大p,也可以是13331这个值

int n,m;
char str[N];
ULL h[N],p[N];//这里是小p,h[N]代表的是数值,p[N]代表的是存储p的多少次方

ULL get(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
int main()
{
    scanf("%d%d%s",&n,&m,str+1);//str+1代表数组从下标是1开始存储

    p[0]=1;
    for(int i=1;i<=n;i++)
    {
        p[i]=p[i-1]*P;//前面是小p,后面是大p,下面也是一样
        h[i]=h[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;
}

最后欢迎大家来到acwing学习算法

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
字符串哈希算法是一种将字符串映射为数字的算法,常用于字符串的比较和匹配。在C++中,可以使用字符串哈希算法来加速字符串的比较操作。 引用\[1\]中的代码示例展示了一个使用字符串哈希算法C++代码。该代码使用了前缀和数组和字符串数组来存储字符串,并通过计算哈希值来比较两个子串是否相等。其中,哈希值的计算使用了前缀和数组和幂运算。 引用\[2\]中的解释指出,使用字符串哈希的目的是为了比较字符串时不直接比较字符串本身,而是比较它们对应映射的数字。这样可以将子串的哈希值的时间复杂度降低到O(1),从而节省时间。 引用\[3\]中的代码示例也展示了一个使用字符串哈希算法C++代码。该代码使用了前缀和数组和字符串数组来存储字符串,并通过计算哈希值来比较两个子串是否相等。与引用\[1\]中的代码类似,哈希值的计算也使用了前缀和数组和幂运算。 综上所述,字符串哈希算法是一种将字符串映射为数字的算法,常用于字符串的比较和匹配。在C++中,可以使用前缀和数组和幂运算来计算字符串哈希值,并通过比较哈希值来判断两个子串是否相等。 #### 引用[.reference_title] - *1* [C++算法题 # 33 字符串哈希](https://blog.csdn.net/weixin_44536804/article/details/123425533)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [字符串哈希(c++)](https://blog.csdn.net/qq_41829492/article/details/120980055)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [AcWing 841. 字符串哈希C++算法)](https://blog.csdn.net/YSA__/article/details/108453403)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值