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
| class RabinKarpSearch { constructor () { this.prime = 101; }
rabinkarpFingerprintHash (str, endLength) { if (endLength === null) endLength = str.length; let hashInt = 0; for (let i = 0; i < endLength; i++) { hashInt += str.charCodeAt(i) * Math.pow(this.prime, i); } return hashInt; }
recalculate (str, oldIndex, newIndex, oldHash, patternLength) { if (patternLength === null) patternLength = str.length; let newHash = oldHash - str.charCodeAt(oldIndex); newHash = Math.floor(newHash/this.prime); newHash += str.charCodeAt(newIndex) * Math.pow(this.prime, patternLength - 1); return newHash; }
strEquals (str1, startIndex1, endIndex1, str2, startIndex2, endIndex2) { if(endIndex1 - startIndex1 !== endIndex2 - startIndex2) return false; while (startIndex1 <= endIndex1 && startIndex2 <= endIndex2) { if (str1[startIndex] !== start2[startIndex2]) { return false; } startIndex1++; startIndex2++; } return true; }
rabinkarpSearch (str, pattern) { let T = str.length, W = pattern.length, patternHash = this.rabinkarpFingerprintHash(pattern, W), textHash = this.rabinkarpFingerprintHash(str, W);
for (let i = 1; i <= T - W + 1; i++) { if (patternHash === textHash && this.strEquals(str, i - 1, i + W - 2, pattern, 0, W - 1)) { return i - 1; } if (i < T - W + 1) { textHash = this.recalculateHash(str, i - 1, i + W - 1, textHash, null); } } return -1; } }
|