字串匹配之RK演算法 學習筆記

2021-08-23 12:42:50 字數 1912 閱讀 5048

rk演算法是rabin-karp演算法的簡稱,是經典的字串匹配演算法,在《演算法導論》上是有介紹的,有興趣的同學可以去看看。

rk演算法的複雜度可以說是比上不足比下有餘,比一般的匹配演算法要好,但是又比不上kmp,sunday等演算法。演算法表現跟快排比較相似,演算法平均複雜度表現較好,但最壞情況時複雜度會相對較高。

rk演算法的核心思想類似於hash函式。對於hash函式有了解的同學應該知道,我們通過hash函式可以將乙個字串對映成乙個數字(hash值)。當兩個字串的hash值不相同時,說明這兩個字串一定不匹配,而相同時則說明兩個字串是有可能匹配的,那麼就需要進一步驗證。

首先給兩個字串,假設str長度為n,pattern長度為m:

char str=;

char pattern=;

我們利用下面的公式可以用pattern計算出乙個值x:

d=26;

l=p.length;

x=p[l-1]+d*(p[l-2]+d*(p[l-3]+...+(p[1]+d*p[0])));

把pattern帶入上面p中,可以求出乙個值pattern_x,這個值就是代表pattern的hash值,或者說是對映值。d的取值根據字串字元的所有可能性值的數量來分配。比如數字0~9,此時d=10,又如字母a~z,此時d=26。

我們可以在str中找到 (n-m+1) 個長度與pattern相同的子串str_sub=,如下:

char str=;

char st1=;

char st2=;

...char st(n-m+1)=;

然後利用上面的公式就計算出這些子串的對映值,與pattern的對映值進行比較後,排除與pattern_x 不相同的對映值,留下相同的值,再取出子串和pattern之間進行字元比較,判斷是否匹配。

還有乙個小問題,就是當pattern較長的時候,pattern_x會比較大,可能會超過最大長度範圍。這時只要取乙個素數q,計算的時候對對映值取餘即可解決這個問題。q取素數會比較好,一般滿足q*d好了,來看**吧

//驗證兩個字串是否相同

bool ismatching(char *str,char *pattern)

} return true;

}//主函式

bool fun(char *str, char *pattern)

//字串開始匹配,對p_code和s_code 進行比較,並更新s_code的值

for (int i = 0; i < size1 - size2+1; i++)

//更新s_code,去掉開頭的值str[i],加上str[i+size2]

s_code = ((s_code - h * (str[i] - 'a'))*d + str[i + size2] - 'a') % q;

} return false;

}

更新str子串對映值可能會稍微難理解一些,舉個例子:

char str=;

char st1=;

char st2=;

st1和st2中間的部分一致,僅首尾變化了,那麼可以推出:

st1_x-st1[0]*pow(d,m-1)%q=(st2_x-st2[m-1])/d;

st2_x=((st1_x-st1[0]*pow(d,m-1)%q)*d+st2[m-1])%q;

st1_x,st2_x為對映值。也就有了我上面**中的公式:

s_code = ((s_code - h * (str[i] - 'a'))*d + str[i + size2] - 'a') % q;
好了,不早了,休息去了~~~~

字串匹配KMP演算法學習筆記

字串匹配,leetcode28題。時間複雜度o mn 的演算法大家都會,題解裡面官方賬號給出的利用字串雜湊判等的o n 演算法也很優秀。本篇的重點是kmp演算法。如果還不是很好理解,可以看labuladong的題解。乙個kmp演算法易理解版本,講解的部分也很清楚。本篇主要是對此題解做乙個補充,個人感...

字串模式匹配 BF演算法和RK演算法

bf演算法 暴力匹配演算法,也叫樸素匹配演算法 效能不是很高。我們在主串中,檢查起始位置分別是0.1.2 n m且長度為n m 1個子串,看有沒有跟模式串匹配的。在a中查詢b,a就是主串,b就是模式串,且a b 最壞的時間複雜度為o n m 但是實際上,這也是常用的,1.模式串和主串的長度都不會太長...

字串演算法學習筆記(三)

回文字串是指正序和反序以向的字串 定義前後指標,看你對應的位置是不是一樣 bool judge string a,int size int front 前指標 int end 後指標 front 0 初始指向字串的頭 end size 1 初始指向字串的尾 while front end front...