KMP演算法Next 函式的乙個應用

2021-09-08 03:21:37 字數 1554 閱讀 9228

記乙個kmp演算法的應用,經典的kmp演算法詳解還是看這裡

問題:給乙個串,求這個串前i位構成的字首由多少個子串組成。

比如aabaabaabaab,前2位是aa,a重複了2次,前6位是aabaab,aab重複了2次,前9位是aabaabaab,aab重複了3次,前12位是aabaabaabaab,aab重複了4次。

先說一下next()函式。pre[i] = j表示   s[1...j] = s[i - j....i];

下面討論當i % (i - pre[i]) == 0 時,例如i = 12, pre[12] = 9:

如圖。s[1...9] == s[3...12];

因為已知 i % (i - pre[i]) == 0; 那麼把i分成 i / (i - pre[i])段。

已知:s3 == t3;

s2 == t2;

s1 == t1;

又因為t3 == s2, t1 == s1。所以 t1 = t2 = t3 = s1 = s2 = s3,也就是說 i / (i - pre[i])這幾段中每一段都相等。

現在回到原問題:求這個串前i位構成的字首由多少個子串組成,只需要找到i / (i - pre[i]) == 0的點i,則共有 i / (i - pre[i])個相同的子串構成字首s[1...i]。

練習:poj 1961, poj 2406

附1961的**:

#include #include 

#include

#include

#include

#include

#include

#define cl(arr, val) memset(arr, val, sizeof(arr))

#define rep(i, n) for(i = 0; i < n; ++i)

#define for(i, l, h) for(i = l; i <= h; ++i)

#define ford(i, h, l) for(i = h; i >= l; --i)

#define l(x) x << 1

#define r(x) x << 1 | 1

#define mid(l, r) (l + r) >> 1typedef

long

long

ll;using

namespace

std;

const

int n = 1000010

;char

s[n];

intpre[n];

int dp[n]; //

這裡加了乙個陣列,記錄到i位置時所構成的字首由多少個子串組成。

intn;

void

next()

}int

main()

}cout

<

}return0;

}

KMP演算法中的next函式

kmp演算法詳解看 next i 表示當模式串t i 與主串失配時,模式串的索引回溯到next i 主串的索引不變 下面串的下標均從0開始 1 i 0 next i max k 0 k 證明模式串next函式的可行性 當t i 與 s j 失配時,即 t i s j 時 可得t 0.i 1 s j ...

KMP演算法的next函式詳解

不得不說,kmp的next函式是在是難以理解,智商拙計。在幾天的斷斷續續理解之後一度想放棄,在得知了它的別名看毛片後重新提起了興趣。kmp演算法理解的難點在於next遞推的理解,也就是說當next j k的時候,如何求出next j 1 的值。先解釋一下next j k的意義。這說明在子串中該j位置...

KMP演算法中next函式的解析

今天花了半天的時間,終於把kmp演算法中的next函式整明白了 先看看next資料值的求解方法 位序 1 2 3 4 5 6 7 8 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2next陣列的求解方法是 1.第一位的next值為0 2.第二位的next值為1 後...