字符串之模式匹配算法(樸素匹配算法,KMP算法)

在一個字符串(目標串)中查找一個子串(模式串)是否存在,如若查找成功返回子串第一個字符位置,否則查找失敗。

暴力匹配

主串的第i個字符如果與子串第一個字符匹配,則依次比較后邊的字符,如果未完全匹配成功,也就是說后邊有一個字符不一致,下一輪的匹配從主串的第i+1個與子串的第一個重新進行,直到匹配成功,返回下標,否則匹配失敗。
該算法效率很低,每次匹配失敗都要重新匹配,最壞情況下O(n*m)的復(fù)雜度,很多時候不能滿足我們的要求。

      int blfind(String S,String T){
        int i=0,j=0;
        while(i<S.length() && j<T.length()){
            if(S[i]==T[j]){
                i++;
                j++;
            }
            else{
                i=i-j+1; 
                j=0;
            }
        }
        if(j==T.length()  return i-j;
        else  return -1;
    }

KMP模式匹配算法

先前我們是在不匹配的時候返回主串的頭部繼續(xù)匹配,我們可以想辦法優(yōu)化這種做法,當主串 S[i]與T[j]失配,我們不再移動i指針,而是移動j指針。大家想一下s[i]之前匹配成功的部分,是不是和T[0]-T[j-1]是一樣的,如果找出T[0]到T[j-1]的相同前后綴的長度,是不是可以直接將j移動到相同前綴的下一個位置。
ababcababa 主串
ababa子串
我們在匹配到'a'和'c' 不等的時候 子串中abab 前綴ab 和后綴ab是相同的,它的前綴和主串中已經(jīng)匹配的后綴一定是相同的 ,所以j指向子串中ababa的第三個字符‘a(chǎn)’,而i仍然指向c ,再次進行匹配,如若失配,不斷地調(diào)整j指針就可以。
如何解決最長公共前后綴的問題,我們采用的next數(shù)組。

void getNext(){  //求next數(shù)組,這里T是模式串
        next[0]=-1; //因為我們是求0到j(luò)-1的,所以0初始化為-1.
        int j=0,k=-1; 
        while(j<T.length()-1){
            if(k==-1 || T[j]==T[k])
                next[++j]=++k; //next[j]表示 當S[i]和T[j]失配時,j指針的位置
            else
                k=next[k];  //這里非常巧妙,回溯的思想。  next[k]是T[k]之前字符串的最長公共前后綴,
// 而T[next[k]]就是這個最長公共前后綴中前綴的最后一個字符
        }
    }
int KMP() {
    int i = 0;
    int j = 0;
    getNext();
    while (i < S.length() && j < T.length()) {
        if (S[i] == T[j]) {
            i++;
            j++;
        }
     else if(next[j]==-1) i++; 
    else  j = next[j];
    }
    if (j == T.length())
        return i - j;
    else
        return -1;
}

它的時間復(fù)雜度是O(n+m),很高效,此外,next數(shù)組的思想還可以解決很多字符串中的問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 字符串匹配KMP算法詳解 1. 引言 以前看過很多次KMP算法,一直覺得很有用,但都沒有搞明白,一方面是網(wǎng)上很少有...
    張晨輝Allen閱讀 2,644評論 0 3
  • title: 串的模式匹配算法之kmptags: 數(shù)據(jù)結(jié)構(gòu)與算法之美author: 辰砂tj 1.引言 首先我們需...
    tojian閱讀 1,153評論 0 0
  • 數(shù)據(jù)結(jié)構(gòu)與算法--KMP算法查找子字符串 部分內(nèi)容和圖片來自這三篇文章: 這篇文章、這篇文章、還有這篇他們寫得非常...
    sunhaiyu閱讀 1,879評論 1 21
  • 引言 字符串匹配一直是計算機科學(xué)領(lǐng)域研究和應(yīng)用的熱門領(lǐng)域,算法的改進研究一直是一個十分困難的課題。作為字符串匹配中...
    潮汐行者閱讀 1,834評論 2 6
  • 與朋友小聚,她喜笑顏開,小口小口啜飲著橙汁,眉角藏不住的笑意。 沒等我開口,她眉飛色舞地說開了。 “你知道嗎? 小...
    靜皈之閱讀 228評論 0 0

友情鏈接更多精彩內(nèi)容