Uh oh!
There was an error while loading. Please reload this page.
forked from trekhleb/javascript-algorithms
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPolynomialHash.js
More file actions
Latest commit
89 lines (76 loc) · 2.22 KB
/
Copy pathPolynomialHash.js
File metadata and controls
89 lines (76 loc) · 2.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
constDEFAULT_BASE=37;
constDEFAULT_MODULUS=101;
exportdefaultclassPolynomialHash{
/**
* @param {number} [base] - Base number that is used to create the polynomial.
* @param {number} [modulus] - Modulus number that keeps the hash from overflowing.
*/
constructor({ base =DEFAULT_BASE, modulus =DEFAULT_MODULUS}={}){
this.base=base;
this.modulus=modulus;
}
/**
* Function that creates hash representation of the word.
*
* Time complexity: O(word.length).
*
* @param {string} word - String that needs to be hashed.
* @return {number}
*/
hash(word){
constcharCodes=Array.from(word).map((char)=>this.charToNumber(char));
lethash=0;
for(letcharIndex=0;charIndex<charCodes.length;charIndex+=1){
hash*=this.base;
hash+=charCodes[charIndex];
hash%=this.modulus;
}
returnhash;
}
/**
* Function that creates hash representation of the word
* based on previous word (shifted by one character left) hash value.
*
* Recalculates the hash representation of a word so that it isn't
* necessary to traverse the whole word again.
*
* Time complexity: O(1).
*
* @param {number} prevHash
* @param {string} prevWord
* @param {string} newWord
* @return {number}
*/
roll(prevHash,prevWord,newWord){
lethash=prevHash;
constprevValue=this.charToNumber(prevWord[0]);
constnewValue=this.charToNumber(newWord[newWord.length-1]);
letprevValueMultiplier=1;
for(leti=1;i<prevWord.length;i+=1){
prevValueMultiplier*=this.base;
prevValueMultiplier%=this.modulus;
}
hash+=this.modulus;
hash-=(prevValue*prevValueMultiplier)%this.modulus;
hash*=this.base;
hash+=newValue;
hash%=this.modulus;
returnhash;
}
/**
* Converts char to number.
*
* @param {string} char
* @return {number}
*/
charToNumber(char){
letcharCode=char.codePointAt(0);
// Check if character has surrogate pair.
constsurrogate=char.codePointAt(1);
if(surrogate!==undefined){
constsurrogateShift=2**16;
charCode+=surrogate*surrogateShift;
}
returncharCode;
}
}