字串匹配。給你兩個字串,尋找其中乙個字串是否包含另乙個字串,如果包含,返回包含的起始位置。
一般匹配字串時,我們從目標字串str(假設長度為n)的第乙個下標選取和ptr長度(長度為m)一樣的子字串進行比較,如果一樣,就返回開始處的下標值,不一樣,選取str下乙個下標,同樣選取長度為n的字串進行比較,直到str的末尾(實際比較時,下標移動到n-m)。這樣的時間複雜度是o(n*m)。
kmp演算法的核心就是計算next陣列。next陣列的計算方法:
next陣列的計算主要跟模式串有關,與文字串並沒有關係,為模式串前後公共最長子序列。
public
class kmp
if(str.charat(i) == dest.charat(j))
if(j == dest.length())
}return
0; }
public
static
int kmpnext(string dest)
if(dest.charat(i) == dest.charat(j))
next[i] = j;
}return next;
}public
static
void
main(string args)
system.out.println(next.length);
}}
kmp研究參考:
假設現在我們面臨這樣乙個問題:有乙個文字串s,和乙個模式串p,現在要查詢p在s中的位置,怎麼查詢呢?
首先,先理清楚了暴力匹配演算法的流程及內在的邏輯:
如果用暴力匹配的思路,並假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置,則有:
如果當前字元匹配成功(即s[i] == p[j]),則i++,j++,繼續匹配下乙個字元;
如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0。相當於每次匹配失敗時,i 回溯,j 被置為0。
舉個例子,如果給定文字串s:「bbc abcdab abcdabcdabde」,和模式串p:「abcdabd」,現在要拿模式串p去跟文字串s匹配,整個過程如下所示:
s[0]為b,p[0]為a,不匹配,執行第②條指令:「如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0」,然後該判斷s[1]跟p[0]是否匹配,相當於模式串要往右移動一位(i=1,j=0)
/**
* 暴力匹配字串演算法
* 思路:
* ①如果當前字元匹配成功(即s[i] == p[j]),則i++,j++
* ②如果失配(即s[i]! = p[j]),令i = i - (j - 1),j = 0 .相當於每次匹配失敗時,i 回溯,j 被置為0。
* 時間複雜度為o(mn)(m、n分別為文字串和模式串的長度)。無需擴充套件儲存空間。
*@param text 文字串
*@param pattern 模式串
*@return pattern返回在text中的位置
*/public
static
intbruteforcesearchpatternintext(string text,string pattern)
int i = 0 ;
int j = 0 ;
while(i < slen && j < plen)else
}//匹配成功,返回模式串p在文字串s中的位置,否則返回-1
if(j == plen)else
}
上面的演算法分析過程中,第6步後,我們會發現s[5]肯定跟p[0]失配。為什麼呢?因為在之前第4步匹配中,我們已經得知s[5] = p[1] = b,而p[0] = a,即p[1] != p[0],故s[5]必定不等於p[0],所以回溯過去必然會導致失配。那有沒有一種演算法,讓i 不往回退,只需要移動j 即可呢?答案是肯定的。這種演算法就是kmp演算法,它利用之前已經部分匹配這個有效資訊,保持i 不回溯,通過修改j 的位置,讓模式串盡量地移動到有效的位置。 KMP字串匹配演算法過程原理
此演算法的關鍵是求next j 若設在進行某一趟匹配比較時在模式p的第j位失配,如果j 0,則目標串指標t進一,模式串指標p回到p0p0 繼續進行下一趟匹配比較。知道了next陣列怎麼使用後,再介紹kmp演算法的原理。樸素模式匹配速度慢的原因是有回溯,而這些回溯是可以避免的。例如 ta b b a ...
KMP演算法及字串匹配學習
kmp演算法是乙個效率很高的字串匹配演算法。我們先看一下樸素的字串匹配演算法,將模式串的每一位與原串進行匹配,如果發生失配現象,則要將原串向前挪一位,以此類推,直到匹配成功為止,設模式串的長度為n,原串的長度為m,則匹配的時間複雜度為o nm kmp演算法改進了失配後的操作,引進了next陣列,加速...
字串匹配演算法 BF及KMP
以 absababcef 與 abce 為例,求串2與串1匹配的第乙個位置的下標 這裡即輸出 5 一般的,我們可以從串1的起始位置開始與串2比較,若相同則兩串都向後移,否則,串1回到第二個位置,串2回到起始位置重新比較。本題用此方法會超時 includeint a 10001 b 10001 int...