java演算法篇KMP演算法及應用

2021-08-28 07:58:20 字數 1460 閱讀 3280

給定兩個字串,判斷是否乙個字串包含另外乙個字串,如果包含,返回起始位置。比如:

string  str1=「abceacmk32acmzq」

string str2=「acm」

可以看出,str1包含兩處str2,下面紅色地方:

abceacmk32acmzq

返回4和10.

遍歷str1,先匹配第乙個,如果不相同,跳過,繼續尋找,如果相同,擷取和str2相同長度的子串,比較是否相同,如果相同,則返回,如果不同繼續尋找,一直到str1到最後乙個字元。**如下

package com.puhui.goosecard.web;

class gfg

string temp = str1.substring(i, i + str2.length());

if (temp.equalsignorecase(str2)) }}

}

輸出結果:410

時間複雜度:

思路一利用了jdk的介面,如果不用呢?思路二:

package com.puhui.goosecard.web;

class gfg else

if (j == chars2.length - 1) }}

}

思路二已經解決了我們的問題,但是是否可以優化呢?當然可以,我們發現如果不匹配,是否可以有效的移動j,而不是回溯到0?

所以,整個kmp的重點就在於當某乙個字元與主串不匹配時,我們應該知道j指標要移動到哪?利用先前比較的結果跳過一些比較。

先看一下思路,先建立乙個部分匹配table

m[i]的值就是,小於i的最長字尾。

比如 p1元素是a,最長字尾是a,i=1,所以m[i]的值為0.

比如p4為abab,最長字尾為ab且滿足2小於i(4)

比如p6為ababab,最長字尾且滿足小於6的是abab,也就是4

比如p9為ababababc,最長字尾且滿足小於9的是0,因小於等於8的裡面沒有c

求出p0···pi的最大相同前字尾長度k

舉例t=abc abcdab abcdabcdabcd

p=abcdabd

下面是我的計算過程

有個這個對映關係,怎麼用,推到過程比較複雜,詳細看下面的連線,

結果就是

p的移動位數=k-m[k],其中k為當前匹配的個數,m[k]為我們上面推到的結果,也就是(0,0,0,0,1,2,0)

移動位數 = 已匹配的字元數 - 最後乙個匹配字元對應的部分匹配值

KMP演算法及應用

kmp演算法用來解決一系列字串單模式匹配問題,其以難理解,難記憶著稱。其next陣列的構造就如同ac自動機中的fail指標,就是如果匹配失敗,字串應從 開始繼續匹配。這裡的next陣列表示 next i 前i個字元的公共最長前字尾長度。覺得對於kmp演算法,這篇寫的不錯 現在來講一下應用。給定兩個字...

KMP演算法詳解及各種應用

kmp演算法詳解 kmp演算法之所以叫做kmp演算法是因為這個演算法是由三個人共同提出來的,就取三個人名字的首字母作為該演算法的名字。其實kmp演算法與bf演算法的區別就在於kmp演算法巧妙的消除了指標i的回溯問題,只需確定下次匹配j的位置即可,使得問題的複雜度由o mn 下降到o m n 在kmp...

KMP演算法模板及各種應用

給定乙個字串,問最多是多少個相同子串不重疊連線構成。kmp的next陣列應用。這裡主要是如何判斷是否有這樣的子串,和子串的個數。若為abababa,顯然除其本身外,沒有子串滿足條件。而分析其next陣列,next 7 5,next 5 3,next 3 1,即str 2.7 可由ba子串連線構成,那...