字符串匹配rk算法c语言,字符串匹配问题(BFRK算法)
1. 題目
有一個主串S={a,b,c,a,c,a,b,d,c},模式串T={a,b,d},請找出模式串在主串中第一次出現的位置
提示:不需要考慮字符串大小寫問題,字符均為小寫字母
2. BF算法
BF算法,又稱爆發匹配算法,簡單來說,就是將模式串一個一個字符與主串進行對比,直到模式串中所有的字符匹配成功。
解法思路:
1、 分別利用計數指針i和j,指示主串S和模式T中當前正待比較的字符位置,i初值為pos,j的初值為1;
2、 如果2個串均為比較到串尾,即i和j均小于等于S和T的長度時, 則循環執行以下的操作:
S[i]和T[j]比較,若相等,則i 和 j分別指示串中下一個位置,繼續比較后續的字符;
若不相等,指針后退重新開始匹配. 從主串的下一個字符串(i = i – j + 2)起再重新和模式第一個字符(j = 1)比較;
3、 如果j > T.length, 說明模式T中的每個字符串依次和主串S找中的一個連續字符序列相等,則匹配成功,返回和模式T中第一個字符的字符在主串S中的序號(i-T.length);否則匹配失敗,返回0;
輔助部分
核心部分
3. RK算法
相對來說,比較字母總是不如比較數字大小來的簡單,那么我們是否可以將字符通過什么方式來計算出對應的數字結果呢?
我們的前輩,Rabin和Karp就很有想法的,通過設計一個哈希公式,利用字符串對應的哈希值來進行比較。即我們已知的模式串可以計算出它的哈希值,同時將主串拆分出與模式串相同長度的子串來計算哈希值,比較兩個哈希值是否相等。
那么問題來了:如何將一個‘bcd’換算成一個哈希值?
通過ASCII表可以直到字母對應的ASCII值,‘a’ = 97。
字母一共有26位,我們可以設計一個26進制
bcb = ('b'-'a')*26^2 + ('c'-'a')*26^1 + ('b'-'a')*26^0;
其中的2次方,也可以認為是模式串長度m減1得來的。
上邊計算字符串的哈希值的邏輯假如理解的話,那我們可以再來想一個問題:主串拆分出來的,相鄰兩個子串,對應的哈希值計算公式是否有交集?是否可以通過前一個子串的哈希值,來求得下一個子串呢?
我們再來看看:
假如相鄰的兩個字符為’bcb’和’cba’,他們的哈希計算分別為
bcb = (‘b’-‘a’)*26^2 + ('c'-'a')*26^1 + ('b'-'a')*26^0;
cba = ('c'-'a')*26^2 + ('b'-'a')*26^1 + (‘a’-‘a’)*26^0;
可以看到,‘bcb‘減去了最高位的‘b’,同時后兩位的多乘了一次26,然后再加上下一個字符串的最低位’a’,得到的結果就是‘cba’的哈希值。
最終的公式
St[i] = (St[i-1] - 26^(m-1)*(S[i]-'a')) * 26 + (S[i+m]-'a')
ps:St[i]為主串中當前子串的哈希值,St[i-1]為前一個子串的哈希值,m為模式串的長度
那么,兩個字符串的哈希值相等,就表示兩個字符串就一定相同嗎?
答案是不一定的,所以我們還需要進一步進行驗證,哈希值相等時,兩個字符串是否真的匹配?
輔助部分
核心部分
總結
以上是生活随笔為你收集整理的字符串匹配rk算法c语言,字符串匹配问题(BFRK算法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux mq发送测试消息,WebSp
- 下一篇: 国二c语言操作题评分标准,全国计算机二级