problem
solution
模板題,沒啥好說的。
kmp匹配:如果成功,就把j==0,從頭開始匹配,答案累加。
codes
#include
#include
#include
using
namespace
std;
const
int maxn = 1010;
char a[maxn], b[maxn];
int n, m, next[maxn], f[maxn];
void pre()
}int kmp()
return ans;
}int main()
return
0;}
kmp
介紹:字串匹配問題:給定主串a和模式串b,求所有b在a中出現的位置。
傳統做法:列舉a串從什麼位置開始與b串匹配,然後驗證是否匹配。最壞情況a=」aaaaaaaaaaaaaaab」,b=」aaaaaab」,複雜度o(mn)。
kmp:最壞情況複雜度o(n)
具體:本質原理:
考慮情況(當前i==5):
i = 123
4567
89a = a b a b a b a
a b a b
b = a b a b a c b
j = 123
4567
89
對於下乙個,不再匹配了。傳統做法就是把b右移一位繼續重頭比較。
但是作為乙個人,我一眼就看出了右移一位也不行,,,,於是,我們移到他下乙個匹配的位置(最長的相同字首和字尾)在開始比較。並且最好是這個匹配的長度盡可能長。
i = 123
4567
89a = a b a b a b a
a b a b
b = a b a b a c b
j = 123
4567
89
再考慮到,b移動後的位置,相對a而言的位置關係,其實是和b移動前的位置關係是一樣的(因為之前的時候ab匹配上了,所以是字母是完全一樣的)。所以就變成了關於b的自我匹配,具體見下方。
兩個步驟:
1、對模式串b進行自我匹配:求乙個陣列next,其中next[i]表示」b中以i結尾的非字首子串」與「b的字首」能匹配的最大長度。ne
xt[i
]=ma
x,ja[i−
j+1,
i]=a
[1,j
] nex
t[i]
=max
,j
a[i−
j+1,
i]=a
[1,j
]。
2、對字串a與b進行匹配:求乙個陣列f,其中f[i]表示」a中以i結尾的子串」與「b的字首」能夠匹配的最長長度。(當長度為b.size()時即得到答案)
具體求法:
1、求next:
咕咕咕
HDOJ 2087 剪花布條
題意 給出主串與模式串,找出主串中不重疊的模式串的個數 思路 kmp,每找到一組匹配時,改變起點位置即可 注意點 無 以下為ac run id submit time judge status pro.id exe.time exe.memory code len.language author 1...
剪花布條 HDOJ2087
題目鏈結 解題思路 這是kmp演算法模板的應用。需要注意的地方就是,這裡的子串需要重新取,所以對於j的處理時要改變一下。include include include const int maxn 1010 int next maxn char str maxn pat maxn void getn...
hdu 2087 剪花布條 kmp
為了紀念第一次用kmp解決一道題,在這寫下了,算是當做乙個模板吧。description 一塊花布條,裡面有些圖案,另有一塊直接可用的小飾條,裡面也有一些圖案。對於給定的花布條和小飾條,計算一下能從花布條中盡可能剪出幾塊小飾條來呢?input 輸入中含有一些資料,分別是成對出現的花布條和小飾條,其布...