字符串哈希:修订间差异

来自三三百科
跳转到导航 跳转到搜索
33DAI留言 | 贡献
33DAI留言 | 贡献
批量导入三三文档
标签新重定向
 
第1行: 第1行:
== 一些好用的语法知识 ==
#REDIRECT [[06-数学相关/05-字符串哈希]]
 
[[Category:三三文档]]
* [http://cpp.33dai.cn/reference/zh/cpp/string/basic_string/substr.html s.substr(pos, count)]
** 返回子串 [pos, pos+count) 。若请求的字串越过字符串的结尾,即 count 大于 size() - pos (例如若 count == npos ),则返回的子串为 [pos, size()) 。
** 可以不写第二个参数,<code>s.substr(pos)</code> 会返回子串 [pos, size())。
* 【C++11起】:[http://cpp.33dai.cn/reference/zh/cpp/container/unordered_set.html unordered_set<T>]:<code>insert</code> 时会把 T 类型元素哈希后放入集合,搜索、插入和移除拥有平均常数时间复杂度。
* 【C++11起】:[http://cpp.33dai.cn/reference/zh/cpp/container/unordered_map.html unordered_map<T,T>]:略
 
== 哈希基础 ==
 
=== 整串哈希到整数 - 单哈希 ===
 
<syntaxhighlight lang="cpp">
const long long MOD = 1000000007;
const int P = 29;
long long getHash(const string &s)
{
    long long hash = 0;
    for (int i = 0; i < s.length(); i++)
        hash = (hash * P + s[i]) % MOD;
    return hash;
}
</syntaxhighlight>
 
=== 整串哈希到整数 - 双哈希 ===
 
<syntaxhighlight lang="cpp">
const long long MOD1 = 1000000007, MOD2 = 998244353;
const int P1 = 29, P2 = 31;
pair<long long, long long> getHash(const string &s)
{
    long long hash1 = 0;
    long long hash2 = 0;
    for (int i = 0; i < s.length(); i++)
    {
        hash1 = (hash1 * P1 + s[i]) % MOD1;
        hash2 = (hash2 * P2 + s[i]) % MOD2;
    }
    return make_pair(hash1, hash2);
}
</syntaxhighlight>
 
=== 整串哈希到整数 - 自然溢出哈希 ===
 
<syntaxhighlight lang="cpp">
const int P = 29;
unsigned long long getHash(const string &s)
{
    unsigned long long hash = 0;
    for (int i = 0; i < s.length(); i++)
        hash = hash * P + s[i];
    return hash;
}
</syntaxhighlight>
 
=== 子串哈希 ===
 
<syntaxhighlight lang="cpp">
// Hash
string s;
const long long MOD = 1000000007;
const int P = 29;
long long myHash[30005];
long long powP[30005];
// 初始化 s[1]~s[n] 的前缀哈希
void initHash(int n)
{
    powP[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        myHash[i] = (myHash[i - 1] * P + s[i] - 'a' + 1) % MOD;
        powP[i] = powP[i - 1] * P % MOD;
    }
}
// 获取 s[l]~s[r] 的哈希值
int getHash(int l, int r)
{
    return (myHash[r] - myHash[l - 1] * powP[r - l + 1] % MOD + MOD) % MOD;
}
</syntaxhighlight>
 
== 循环节判断 ==
 
如果 <code>s[1 ~ n-len] == s[len+1 ~ n]</code>,那么 <code>s[1~len]</code> 是一个循环节。

2026年5月20日 (三) 18:24的最新版本