O(1) 取子串Hash
O(1) 比较
通常使用 131 做乘法自然溢出即可满足要求(碰撞概率很小),如果数据不允许,可以使用两组 hash 避免哈希碰撞。也可以使用 64 位整数。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; constexpr int N = 1e6; template <typename T, size_t size, T multiplier> struct hash_table { T h[size], k[size]; hash_table() { k[0] = 1; for (int i = 1; i < size; i++) { k[i] = k[i - 1] * multiplier; } } hash_table(const char str[]) { new (this) hash_table(); init(str); } void init(const char str[]) { memset(h, 0, sizeof(h)); for (int i = 1; str[i]; ++i) { h[i] = h[i - 1] * multiplier + str[i]; } } /** [start, end) */ T get(size_t start, size_t end) { return h[end - 1] - h[start - 1] * k[end - start]; } }; int main() { char s[] = "bananananana"; hash_table<size_t, 100, 131> ht(s); for (int i = 0; i < 7; i++) { int end = i + 2; printf("%d -> %d: [%.2s] %lld\n", i, end, s + i, ht.get(i, end)); } return 0; }
本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.