[JAVA][算法] [字符串匹配]KMP
我們?yōu)槭裁葱枰狵MP?
在字符串匹配問題中,我們需要找到匹配串pattern在原串text中的位置,一種顯而易見的思路就是暴力匹配,如圖所示,我們把pattern放置到text中的每個位置進(jìn)行比較即可。
但是大家可以發(fā)現(xiàn),這種方式的時間復(fù)雜度太高了,達(dá)到了O(pattern.length * text.length),我們是否可以進(jìn)一步進(jìn)行優(yōu)化呢?在第一次匹配時,abaa和abab的最后一個字符不匹配,前面aba都匹配好了,移動了一位之后,發(fā)現(xiàn)前面又匹配不上了,這次移動相當(dāng)于多此一舉。換句話說,我們每次移動應(yīng)當(dāng)讓前面仍然保持匹配狀態(tài),直接比較后面的位置。
本例中應(yīng)當(dāng)直接移動兩位,讓aaab和abaa比較,這也就是KMP的基本思想了。
基礎(chǔ)知識
求匹配數(shù)組maxMatchLens
那么我們?nèi)绾巫龅皆谝苿拥倪^程中保證前面的匹配狀態(tài)呢?下圖可以清晰地描述:
發(fā)生匹配錯誤的字符為c,左端為abab,在移動的時候,要保證真前綴和真后綴相等且長度最大(選了較小的會忽略可能正確的結(jié)果),對于abab:
真前綴:a ab aba
真后綴:b ab bab
也就是說,我們需要找到pattern中所有位置,相匹配的真前綴與真后綴中,最長的字符串的長度,這也就是我們經(jīng)常聽到的next數(shù)組了,這里我們用maxMatchLens來表示,如下圖所示的例子中,假設(shè)我們已經(jīng)求出來前面所有的值了,最后一個值如何求解呢?
舉例: 第五位 c
| currentLen | 2 | 1 | 0 |
| pattern.charAt(currentLen) | a | b | a |
| i | 4 | 4 | 4 |
| pattern.charAt(i) | c | c | c |
| 處理 | 1.while字符不相等 | 1.while字符不相等 | 3.賦值 maxMatchLens[4] = currentLen=0; |
KMP匹配
返回起始坐標(biāo) (text里面找pattern)
匹配的思路與求maxMatchLens的思路基本一致,即按照最長、次長的順序進(jìn)行移位匹配,代碼如下:
參考鏈接:https://leetcode-cn.com/problems/longest-happy-prefix/solution/ni-zhen-de-li-jie-kmpma-jiao-ni-xun-su-zhang-wo-bi/
參考鏈接:https://blog.csdn.net/V_0617/article/details/79114860
總結(jié)
以上是生活随笔為你收集整理的[JAVA][算法] [字符串匹配]KMP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 观点:我们为什么需要威胁情报?
- 下一篇: MongoDB (芒果)安装说明创建与插