011 資料結構與演算法 字串匹配演算法

2021-10-06 01:37:02 字數 2665 閱讀 9566

思路:

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;

執行過程

}//如果j>t[0],則找到了匹配模式

if (j > t[0]) else

}d.e.knuth, j.h.morris 和 v.r.pratt 共同發表模式匹配演算法, 稱之克魯特-莫里斯-普拉特演算法. 簡稱 kmp 演算法

思考:在上述列子中,第一次執行時

當 i = 3 , j = 3 時,我們發現 c != d,同時我們也可以得到一些有用的資訊

比如  s[1] = t[1], s[2] = t[2], 要不然 i 和 j 是不會到3的啊

我們直接看一下子串的前兩個字元 t[1] 和 t[2],發現 t[1] = a, t[2] = b, a != b , 所以 t[1] != t[2],又因為t[2] = s[2], 所以 t[1] != s[2]

此時我們回顧一下第二次比較的什麼

第二次比較的不就是t[1] 和 s[2]麼?那第一次的結果其實已經證明了的東西,我還需要在遍歷一次麼?答案是不需要的

所以 i 不需要回到 2,i  直接來到3,也就是說當發現不匹配時,i 是沒有必要回退到上次匹配的首頁的下一位的

換句話說當發現與子串不相同時,i不需要回退,但是如果第一位就不相同,i是需要移動到下一位的

在上面這個例子中如果是第二位或者第三位不相同 j 都要回到 1

再舉個例子

主串為:aaab

模式串為: aab

肉眼可見  當i = 2時,模式串第一次出現在主串中

如果i不回退,i = 3, 而正確答案i = 2 就完美錯過了啊,如果避免這個問題呢,答案是讓 j 回退 2

s[3] = j[2],i++,j++,s[4] = b,j[3] = b,完全匹配,i = 5-3 = 2    5因為只要匹配成功i就會自加,3是子串的長度

為什麼j 要回退到2呢?

因為 當i =3發生不匹配時,證明主串的前兩位和子串的前兩位肯定是相同的,有因為子串的前兩位是相同的都是a

如果得到j應該回退的位置是mvp演算法的核心,我們用乙個名字叫next陣列來儲存

通過計算返回子串t的next陣列

eg: next[i]  翻譯成中文就是,主串的第i個字元與模式串不一樣時,模式串的索引應該回到next[i]這個位置

特殊情況:第乙個位置就不一樣時,i = 1,i 是需要移動到下一位的也就是i++, j 需要回到第一位,而i移動的時候,j也會移動,所以設定 next[1] = 0,j++ 後,j = 1

(注意字串t[0]中是儲存的字串長度; 真正的字元內容從t[1]開始;)

void get_next(string t,int *next)else}}

上面的例子中  模式串aabnext陣列為012

int count = 0;

//kmp 匹配演算法(1)

//返回子串t在主串s中第pos個字元之後的位置, 如不存在則返回0;

int index_kmp(string s,string t,int pos)else

}if (j > t[0]) else

}

next陣列優化

//kmp 匹配演算法(2)

//求模式串t的next函式值修正值並存入nextval陣列中;

void get_nextval(string t,int *nextval)else}}

int index_kmp2(string s,string t,int pos)else

}if (j > t[0]) else

}

資料結構與演算法 字串匹配 BF演算法

又稱暴力匹配演算法,是一種樸素的模式匹配演算法 給定主串 s bilibili 和子串 t bilididi 1.主串 s 第一位開始與子串 t 第一位匹配,b 與 l 不匹配,匹配失敗 2.主串 s 第二位開始與子串 t 第一位匹配,i 與 l 不匹配,匹配失敗 3.主串 s 第三位開始與子串 t...

資料結構與演算法 字串匹配 BM演算法

單模式串匹配 bf 演算法和 rk 演算法 bm 演算法和 kmp 演算法 多模式串匹配演算法 trie 樹和 ac 自動機 bm演算法的核心思想是通過將模式串沿著主串大踏步的向後滑動,從而大大減少比較次數,降低時間複雜度。而演算法的關鍵在於如何兼顧步子邁得足夠大與無遺漏,同時要盡量提高執行效率。這...

資料結構 字串匹配

演算法 如下,包括暴力匹配和kmp演算法。參考 include stringmatching.h stringmatching stringmatching void stringmatching stringmatching void 返回子串t在主串s中第pos個字串之後的位置。若不存在,則返回...