Rabin-Karp là một thuật toán tìm kiếm mẫu khác để tìm mẫu theo cách hiệu quả hơn. Nó cũng kiểm tra mẫu bằng cách di chuyển từng cửa sổ một, nhưng không cần kiểm tra tất cả các ký tự cho tất cả các trường hợp, nó sẽ tìm giá trị băm. Khi giá trị băm được khớp, thì chỉ nó cố gắng kiểm tra từng ký tự. Quy trình này làm cho thuật toán hiệu quả hơn.
Độ phức tạp thời gian là O (m + n), nhưng trong trường hợp xấu nhất, nó là O (mn).
Đầu vào và Đầu ra
Input: Main String: “ABAAABCDBBABCDDEBCABC”, Pattern “ABC” Output: Pattern found at position: 4 Pattern found at position: 10 Pattern found at position: 18
Thuật toán
rabinKarpSearch(text, pattern, prime)
Đầu vào - Văn bản chính và mẫu. Một số nguyên tố khác của tìm vị trí băm
Đầu ra - vị trí nơi các mẫu được tìm thấy
Begin patLen := pattern Length strLen := string Length patHash := 0 and strHash := 0, h := 1 maxChar := total number of characters in character set for index i of all character in pattern, do h := (h*maxChar) mod prime done for all character index i of pattern, do patHash := (maxChar*patHash + pattern[i]) mod prime strHash := (maxChar*strHash + text[i]) mod prime done for i := 0 to (strLen - patLen), do if patHash = strHash, then for charIndex := 0 to patLen -1, do if text[i+charIndex] ≠ pattern[charIndex], then break the loop done if charIndex = patLen, then print the location i as pattern found at i position. if i < (strLen - patLen), then strHash := (maxChar*(strHash – text[i]*h)+text[i+patLen]) mod prime, then if strHash < 0, then strHash := strHash + prime done End
Ví dụ
#include<iostream> #define MAXCHAR 256 using namespace std; void rabinKarpSearch(string mainString, string pattern, int prime, int array[], int *index) { int patLen = pattern.size(); int strLen = mainString.size(); int charIndex, pattHash = 0, strHash = 0, h = 1; for(int i = 0; i<patLen-1; i++) { h = (h*MAXCHAR) % prime; //calculating h = {d^(M-1)} mod prime } for(int i = 0; i<patLen; i++) { pattHash = (MAXCHAR*pattHash + pattern[i]) % prime; //pattern hash value strHash = (MAXCHAR*strHash + mainString[i]) % prime; //hash for first window } for(int i = 0; i<=(strLen-patLen); i++) { if(pattHash == strHash) { //when hash values are same check for matching for(charIndex = 0; charIndex < patLen; charIndex++) { if(mainString[i+charIndex] != pattern[charIndex]) break; } if(charIndex == patLen) { //the pattern is found (*index)++; array[(*index)] = i; } } if(i < (strLen-patLen)) { //find hash value for next window strHash = (MAXCHAR*(strHash - mainString[i]*h) + mainString[i+patLen])%prime; if(strHash < 0) { strHash += prime; //when hash value is negative, make it positive } } } } int main() { string mainString = "ABAAABCDBBABCDDEBCABC"; string pattern = "ABC"; int locArray[mainString.size()]; int prime = 101; int index = -1; rabinKarpSearch(mainString, pattern, prime, locArray, &index); for(int i = 0; i <= index; i++) { cout << "Pattern found at position: " << locArray[i]<<endl; } }
Đầu ra
Pattern found at position: 4 Pattern found at position: 10 Pattern found at position: 18