KMP 子串查詢演算法

2021-08-20 03:10:49 字數 2001 閱讀 9515

如何在目標字串s中,查詢是否存在子串p? 

樸素解法:

//字串s中查詢子串p的位置

int sub_str_index(const char* s, const char* p)

ret = equal ? i : -1;

}return ret;

}

樸素解法的乙個優化線索

因為,pa != pb != pc  且 pc== sc;  所以,pa != sb pa != sc

結論,子串p右移1位比較,沒有意義。完全可以無腦右移3位再比較

示例

偉大的發現

-匹配失敗時的右移位數與子串本身相關,與目標串無關 

-移動位數=已匹配的字元數-對應的部分匹配值 (當部分匹配值為0時,即可無腦右移已匹配的字元數)

-任意子串都存在乙個唯一的部分匹配表 

部分匹配表示例

字首:除了最後—個字元以外,乙個字串的全部頭部組合 

字尾:除了第—個字元以外,—個字串的全部尾部組合 

部分匹配值:字首和字尾最長共有元素的長度 

// 相當於子串的自身比較,例如:

// abcdabd i = 1, 2, 3, 4

// abcdabd ll : 兩個含義:當前正在匹配的下標 或 部分匹配值

if(p[i] == p[ll])

cout << "ret[" << i << "] : " << ll << endl << endl;

ret[i] = ll; //部分匹配表存放部分匹配值}}

部分匹配表的使用(kmp演算法)

kmp子串查詢演算法的實現 

#include #include #include using namespace std;

int* make_pmt(const char* p) //o(n)

if(p[ll] == p[i])

ret[i] = ll; //部分匹配表存放部分匹配值}}

return ret;

}int kmp(const char* s, const char* p) //o(m)+o(n)=o(m+n)

if(s[i] == p[j])

if(j == p1) // 成功完全匹配}}

free(pmt);

return ret;

}int main()

發現從求pmt,到kmp兩者的步驟非常相似...

KMP 演算法,search 子串

網上看了好多關於kmp演算法的,但是都是看的不清不楚的,用了好多術語,不明白,後來自己根據結果倒推了過程,不知對不對,暫時先記下來,kmp演算法,需要預先處理子串,然後建立乙個int型別next陣列 名字無所謂,主要是儲存一些關於子串的資訊 這裡有幾點要注意 next陣列計算方法 假定j為數字下標,...

快速查詢子串演算法KMP原始碼

kmp演算法最難理解的就是它的next陣列的求法。個人理解就是當模式串 pattern string 某個位置和主串不匹配時,將模式串的當前的位置從字首位置轉移到對應的字尾位置。位置0 1234 56字元a baba bbnext 未優化 10 0123 4next 優化後 10 10 10 4未優...

alg4 子字串查詢 KMP演算法

kmp演算法的基本思想是當出現不匹配時,就能知曉一部分文字內容 因為在匹配失敗之前它們已經和模式相匹配 我們可以利用這些資訊避免將指標回退到所有這些已知的字元之前。kmp演算法的主要思想是提前判斷如何重新開始查詢,而這種判斷只取決於模式本身。在kmp子字串查詢演算法中,不會回退文字指標i,而是使用乙...