KMP 大問題分割成小問題 分步理解

2022-06-24 17:15:11 字數 1651 閱讀 3183

分解成小問題:

求出next陣列

當pattern與text不匹配時,按照next陣列的指示進行跳轉

字串 absdc:

字首:a, ab, abs, absd, absdc

真字首:a, ab, abs, absd

字尾:c, dc, sdc, bsdc, absdc

真字尾:c, dc, sdc, bsdc

用於next陣列的應該是真字首與真字尾的公共子串最大長度。

int tmp = 0, res = 0;

int len = s.length();

int j = 0;

for(int i = 1; i < len; i++)

else if(s[i] != s[j])

}}cout << res;

這個是針對確定的乙個字串的比較暴力的演算法,一旦不匹配就從頭重新匹配。(因為針對確定的乙個字串,所以字首都是從第乙個開始的嘛,不匹配就從頭再判斷咯)

其實構建next陣列的本質就是求解pattern中的 字首子串中的 最長公共前字尾。

next[i] = k pattern[i]之前的子串中,存在最長長度為k的公共前字尾,因此可以把當前不匹配的text的位,與k+1位pattern再次進行比較。(但是因為陣列是從0開始的,所以下標可以直接被賦值next陣列中的值,而不用+1
也就是它需要進行len-1次的上一節的行為。同時需要考慮盡可能重複利用結果(有點像kmp中patterntext不匹配時就使用next陣列跳躍,這裡也是利用next陣列中已經產生的資料進行跳躍。

想象兩個指標,乙個指向字首的最後,乙個指向字尾的最後,當它們的值不同時:

i -> 字首最後 j->從0到len-1迴圈的下標

pattern[i] != pattern[j]時

讓i往回走,類似kmp

i = next[i];//現在i是最長公共前字尾中字首的後一位的下標

當它們的值相同時,那公共前字尾的長度增加:

next[++j] = ++i;注意next陣列的下標對應的迴圈變數j

使用next時,記住使用的下標的值是不匹配的當位。

//字串陣列下標從0開始

int next[pattern.length()+1];

next[0] = -1;//用於pattern與text進行匹配且第乙個數不匹配時

int i = 0, j = -1;//i是迴圈變數,j是代表字首最後比較的下標

next[++i] = ++j;//初始化

int len = pattern.length();

while(i < len)

j = 0; i = 0;//j是text的下標,i是pattern的下標

while(j < text.length())

//迴圈退出,說明i<0或者當前位匹配

i++; j++;//繼續向後匹配

//進行跳出判斷

if(i == len)

return j-len

}

小問題,大問題?

有一天美國通用汽車公司的龐帝雅克 pontiac 部門收到一封客戶抱怨信,上面是這樣寫的 這是我為了同一件事第二次寫信給你,我不會怪你們為什麼沒有回信給我,因為我也覺得這樣別人會認為我瘋了,但這的確是乙個事實。我們家有乙個傳統的習慣,就是我們每天在吃完晚餐後,都會以冰淇淋來當我們的飯後甜點。由於冰淇...

大整數分割成 多個小整數問題(二)

問題 分硬幣問題,假設sum代表總的錢數,陣列a中的元素代表有的單個硬幣,問sum最少需要a中的幾個硬幣 可以重複 加起來才能得到sum?比如 int a int sum 63 那麼最少就是3個21的才能得到sum ps 貪婪演算法在這個例子中就不成立,所以貪婪方法沒有用 演算法1 和大整數分割成 ...

解決KMP看高畫質電影背景聲大說話聲小問題

那麼到底是什麼原因造成的呢?網上搜了一下,原因如下 一般情況下,由於杜比數字ac 3 5.1提供的環繞聲系統由五個全頻域 3 20000hz 聲道加乙個超低音 3 120hz 聲道組成,聲道大部份時間負責重放人物對白的部份。前置主左 右聲道則是用來彌補在螢幕 以外或不能從螢幕看到的動作及其他聲音,後...