其他分享
首页 > 其他分享> > 字符串哈希

字符串哈希

作者:互联网

#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;
}

 

标签:ULL,int,哈希,long,str,字符串
来源: https://www.cnblogs.com/yahh/p/16389618.html