當前稿件版本1.0
**
今天為了noip提高組的模擬準備,早上起來——默寫kmp吧!好,提交:tle;改改改:tle;我不信!:tle;58%%rs@^$:wa
終於在一天的努力後,把kmp給a了。
痛心疾首,決心寫乙個kmp的詳解,不要讓其他人掉入這個坑里了
**在**不用管!只用知道它是乙個高效的字串匹配演算法就行了。
ac自動機就是在trie樹上做乙個kmp罷了。
故學好kmp還是蠻重要地。
嘿嘿嘿,開始模擬吧!
等等!直接開始模擬會有一些奇怪的問題,不利於理解,畢竟這個部落格打的是超詳好懂理解的標題,自然要先做出一些規定:
1. father son均為從0開始的string型別,father son分別為父串和子串
2. pmt為部分匹配值,為了和son保持一致,也是從0開始。
3. 變數i為father正在對比的字元下標【模擬中以紅色標出】
4. 變數compared為son正在對比的字元下標【模擬中以黃色標出】
5. compared也代表了有幾個字元匹配成功
好了開始模擬吧
以6do8_8__8q找出8__8q為例
這個是最原始的**:
add為下標的號碼,father、son同規定所示
有乙個陣列,名為pmt(partial match table),部分匹配值的英文全稱的簡寫。通過pmt_find
函式求出其值(這裡省略,下文會提及)
開始對比,初始化compared=0;for(i=0;i部分匹配值的官方解釋是:」字首」和」字尾」的最長的共有元素的長度。
「部分匹配」的實質是,有些字串頭部和尾部會有重複。比如,」abcdab」之中有兩個」ab」,那麼它的」部分匹配值」就是2(」ab」的長度)。搜尋詞(即i、compared移動)移動的時候,第乙個」ab」向後移動4位(字串長度-部分匹配值),就可以來到第二個」ab」的位置。
那麼怎麼求呢,就是根據上一位以及上一位的字串來進行判斷求max(因為字串的部分匹配值總是比母串大,所以直接搜就可以了)
- 貌似還是有點難懂啊,就拿ababac說吧,假設正在第3個a上做判斷,前面有了個aba,如果這裡(即以第三個a為最後乙個字元)有乙個aba——豈不美哉?
- 假設正在c上做判斷,前面有乙個abab,如果這裡有乙個abac不好麼?然而沒有…好的,那麼此時是不是搜第二個b的ba?不是的,ababa的最長出現字串是ab(ba也可以,但是c後面是a,a的視角中是ab),因此ab==ac?不,這麼一直搜下去,沒有……那就是0唄!
不懂的朋友們,拿起紙和筆,來手動按照下面的原始碼來一發模擬吧!自己動手才好理解
/*build 2017.7.22*/
#include
#include
#include
using
namespace
std;
const
int maxlenth=100001;
bool flag=0;
int want;
int pmt[maxlenth];
string father;
string son;
void pmt_find()
if(son[comparing]==son[i]) ++comparing;
pmt[i]=comparing;
}}void solve()
if(father[i]==son[compared]) ++compared;*/
//優化
while(compared and father[i]!=son[compared])
if(father[i]==son[compared]) ++compared;
if(compared==want)
}}int main()
KMP演算法詳講
一 簡單匹配演算法 先來看乙個簡單匹配演算法的函式 int index bf char s char t int pos else j nextval j 子串移動到第nextval j 個字元和主串相應字元比較 下面是我寫的kmp模式匹配程式,各位可以測試一下。include include in...
理解KMP演算法
由暴力匹配引入kmp演算法 問題 有乙個文字串s,和乙個模式串p,現在要查詢p在s中的位置。如果用暴力匹配的思路,並假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置,則有 示例 上面s,下面p 比如從a這裡開始匹配上了 一直這樣匹配下去 到這裡匹配不上了 就回滾回去重新開始 這種回滾的問題...
KMP演算法(超容易理解的next陣列求法)
我想,既然知道kmp演算法了,自然對於其具體如何運作也是有一定的了解的,我也沒必要再大費口舌講廢話,大家一定查過很多資料,但是其實也都看的一知半解,好像自己懂了但是又沒有理解透,特別是next陣列的求法感覺很蛋疼,那麼我就來給大家解決一下這個next陣列的問題吧,如果對kmp演算法沒有概念的同學請先...