洛谷 P3375 KMP KMP字串匹配

2021-10-25 07:18:32 字數 2237 閱讀 1418

題目描述

給出兩個字串 s

1s_1

s1​和 s

2s_2

s2​,若 s

1s_1

s1​的區間 [l,

r][l

,r][l, r][l,r]

[l,r][

l,r]

子串與 s

2s_2

s2​完全相同,則稱 s

2s_2

s2​在 s

1s_1

s1​**現了,其出現位置為 l。

現在請你求出 s

2s_2

s2​ 在 s

1s_1

s1​中所有出現的位置。

定義乙個字串 s 的 bor

derborder

border

為 s 的乙個非 s 本身的子串 t,滿足 t 既是 s 的字首,又是 s 的字尾。

對於 s

2s_2

s2​,你還需要求出對於其每個字首 s′s'

s′的最長 bor

derborder

border

t ′t'

t′的長度。

輸入格式

第一行為乙個字串,即為 s

1s_1

s1​。

第二行為乙個字串,即為 s

2s_2

s2​。

輸出格式

首先輸出若干行,每行乙個整數,按從小到大的順序輸出s

2s_2

s2​ 在 s

1s_1

s1​**現的位置。

最後一行輸出 ∣s2

∣|s_2|

∣s2​

∣個整數,第 i 個整數表示 s

2s_2

s2​的長度為 i 的字首的最長 border 長度。

輸入輸出樣例

輸入 #1

abababc

aba輸出 #113

0 0 1

說明/提示

樣例 1 解釋

對於 s

2s_2

s2​長度為 3 的字首 aba

abaab

a,字串 a 既是其字尾也是其字首,且是最長的,因此最長 bor

derborder

border

長度為 1。

資料規模與約定

本題採用多測試點**測試,共有 3 個子任務。

對於全部的測試點,保證 1≤∣

s1∣,

∣s2∣

≤106

,s1,

s21 ≤∣s 1∣,∣s 2∣≤10^6,s_1, s_2

1≤∣s1∣

,∣s2

∣≤10

6,s1

​,s2

​ 中均只含大寫英文本母。

解題思路

kmp 的精髓在於,對於每次失配之後,我都不會從頭重新開始列舉,而是根據我已經得知的資料,從某個特定的位置開始匹配;而對於模式串的每一位,都有唯一的「特定變化位置」,這個在失配之後的特定變化位置可以幫助我們利用已有的資料不用從頭匹配,從而節約時間。

這篇kmp的講稿不錯:kmp字串匹配.

**

#include

#include

#include

#include

#include

#include

using namespace std;

char a[

2000000

],b[

2000000];

int l1,l2,j,p[

2000000];

int main()

j=0;for

(int i=

1;i<=l1;i++)}

for(int i=

1;i<=l2;i++

)printf

("%d "

,p[i]);

}

洛谷 P3375 模板 KMP字元匹配

如題,給出兩個字串s1和s2,其中s2為s1的子串,求出s2在s1中所有出現的位置。為了減少騙分的情況,接下來還要輸出子串的字首陣列next。輸入格式 第一行為乙個字串,即為s1 第二行為乙個字串,即為s2 輸出格式 若干行,每行包含乙個整數,表示s2在s1中出現的位置 接下來1行,包括length...

洛谷 P3375 KMP字串匹配

題目描述 給出兩個字串s1和s2,其中s2為s1的子串,求出s2在s1中所有出現的位置。為了減少騙分的情況,接下來還要輸出子串的字首陣列next。輸入輸出格式 輸入格式 第一行為乙個字串,即為s1 僅包含大寫字母 第二行為乙個字串,即為s2 僅包含大寫字母 輸出格式 若干行,每行包含乙個整數,表示s...

洛谷 P3375 模板 KMP字串匹配

題目大意 給出n長的字串s1,m長的字串s2,求出s2在s1中所有出現的位置。用kmp做,先輸入每一次s2出現的位置,然後輸出s2的字首陣列next。題解 kmp next i 表示需要匹配的字串的最長公共前字尾的長度。怎麼求next i 呢?首先初值next 1 0,j 0 對於每乙個如果s2 j...