什么是字符串哈希?
字符串散列是将字符串转换为整数的方法,称为该字符串的散列。
理想的散列是冲突可能性最小的散列(即具有相同散列的 2 个不同字符串)。
多项式滚动哈希函数
在这种散列技术中,字符串的散列计算如下:
其中 P 和 M 是一些正数。 s[0], s[1], s[2] … s[n-1] 是分配给英文字母表中每个字符的值 (a->1, b->2, … z->26)。
P 和 M 的适当值
- P:P的值可以是大致等于使用的不同字符数的任何质数。
例如:如果输入字符串只包含英文字母的小写字母,那么P=31就是P的合适值。
如果输入字符串包含大写和小写字母,则 P = 53 是合适的选项。 - M:两个随机字符串碰撞的概率与m成反比,因此m应该是一个很大的素数。
M = 10 ^9 + 9是一个不错的选择。
下面是使用多项式散列函数的字符串散列的实现:
C++
// C++ implementation of the
// Polynomial Rolling Hash Function
#include
using namespace std;
// Function to calculate
// the hash of a string
long long polynomialRollingHash(
string const& str)
{
// P and M
int p = 31;
int m = 1e9 + 9;
long long power_of_p = 1;
long long hash_val = 0;
// Loop to calculate the hash value
// by iterating over the elements of string
for (int i = 0; i < str.length(); i++) {
hash_val
= (hash_val
+ (str[i] - 'a' + 1) * power_of_p)
% m;
power_of_p
= (power_of_p * p) % m;
}
return hash_val;
}
/// Driver Code
int main()
{
// Given strings
string str1 = "geeksforgeeks";
string str2 = "geeks";
cout << "Hash of '" << str1 << "' = "
<< polynomialRollingHash(str1);
cout << endl;
}
Java
// Java implementation of the
// Polynomial Rolling Hash Function
class GFG{
// Function to calculate
// the hash of a String
static long polynomialRollingHash(String str)
{
// P and M
int p = 31;
int m = (int)(1e9 + 9);
long power_of_p = 1;
long hash_val = 0;
// Loop to calculate the hash value
// by iterating over the elements of String
for(int i = 0; i < str.length(); i++)
{
hash_val = (hash_val + (str.charAt(i) -
'a' + 1) * power_of_p) % m;
power_of_p = (power_of_p * p) % m;
}
return hash_val;
}
// Driver Code
public static void main(String[] args)
{
// Given Strings
String str1 = "geeksforgeeks";
String str2 = "geeks";
System.out.print("Hash of '" + str1 + "' = " +
polynomialRollingHash(str1));
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 implementation of the
# Polynomial Rolling Hash Function
# Function to calculate
# the hash of a string
def polynomialRollingHash(str):
# P and M
p = 31
m = 1e9 + 9
power_of_p = 1
hash_val = 0
# Loop to calculate the hash value
# by iterating over the elements of string
for i in range(len(str)):
hash_val = ((hash_val + (ord(str[i]) -
ord('a') + 1) *
power_of_p) % m)
power_of_p = (power_of_p * p) % m
return int(hash_val)
# Driver Code
if __name__ == '__main__':
# Given string
str1 = "geeksforgeeks"
print("Hash of '{}' = {}".format(
str1, polynomialRollingHash(str1)))
# This code is contributed by Shivam Singh
C#
// C# implementation of the
// Polynomial Rolling Hash Function
using System;
class GFG{
// Function to calculate
// the hash of a String
static long polynomialRollingHash(String str)
{
// P and M
int p = 31;
int m = (int)(1e9 + 9);
long power_of_p = 1;
long hash_val = 0;
// Loop to calculate the hash value
// by iterating over the elements of String
for(int i = 0; i < str.Length; i++)
{
hash_val = (hash_val + (str[i] -
'a' + 1) * power_of_p) % m;
power_of_p = (power_of_p * p) % m;
}
return hash_val;
}
// Driver Code
public static void Main(String[] args)
{
// Given Strings
String str1 = "geeksforgeeks";
String str2 = "geeks";
Console.Write("Hash of '" + str1 + "' = " +
polynomialRollingHash(str1));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
Hash of 'geeksforgeeks' = 111226362
时间复杂度: O(N)
辅助空间:O(1)