如何在目標字串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,而是使用乙...