字符串哈希

复制代码
#include <bits/stdc++.h>
/**
 * @brief 
 * b站视频:https://www.bilibili.com/video/BV1Ha411E7re?spm_id_from=333.337.search-card.all.click&vd_source=13dfbe5ed2deada83969fafa995ccff6
 * 其他资料:https://oi-wiki.org/string/hash/
 * /
using namespace std;
typedef unsigned long long ULL;
const int P = 131;
string str("abcdefghijklmn");
const ULL N = 100021;
ULL h[N], p[N];
int main()
{
    /**
     * @brief 
     * 字符串哈希;;
     * 一个字符串的哈希值是前缀和, 字串是区间和;
     * 
     * CRASH: 字符串不一样,但是Hash函数值一样,称为“哈希碰撞”;
     * SOLVE: 巧妙设置p 和 M值,保证p和M互质;
     * p 通常取 131 || 13331;
     * M 通常区 2^64; h定义为ULL(unsigned long long);;;; 超过自动取模;
     * 
     */
    // Hash Init
    h[0] = 0; p[0] = 1;
    for(int i = 1; i < str.size(); ++i) {
        p[i] = p[i-1]*P;
        h[i] = h[i-1]*P + str[i];
    }
    for(int i = 0; i < str.size(); ++i) {
        cout<<h[i]<<" ";
    }
    // 区间和;;
    // h[left, right] = h[right] - h[left - 1] *p[right - left + 1] ~~~`p[elem] 为字串的长度;
    // Find:
    ULL Sab = h[2] - h[0]*p[3];
    cout<<Sab;
    string str2("abcde");
    ULL sb[N];
    sb[0] = 0;
    for(int i = 1; i < str2.size(); ++i) {
        sb[i] = sb[i-1]*P + str2[i];
    }
    cout<<endl;
    if(sb[3] == h[3]) {
        cout<<"YES";
    } else {
        cout<<sb[3]<<" "<<h[3];
    }
    return 0;
}
复制代码

 

posted @   golemon  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示