字串匹配 BKDRhash KMP

2022-08-03 22:33:14 字數 1871 閱讀 4931

題目描述

給定乙個字串 a 和乙個字串 b ,求 b 在 a 中的出現次數。a 和 b中的字元均為英語大寫字母或小寫字母。 a 中不同位置出現的 b 可重疊。

輸入格式

輸入共兩行,分別是字串 a 和字串 b 。

輸出格式

輸出乙個整數,表示 b 在 a 中的出現次數。

樣例一input

zyzyzyz

zyzoutput

3限制與約定

對於100%的資料:1≤a,b的長度≤106,a、b僅包含大小寫字母。1≤a,b的長度≤106

,a、b僅包含大小寫字母。

時間限制:1s1s

空間限制:256mb256mb

t這道題題意很簡單,是字串hs和kmp的裸題

字串hs是乙個準確率不是100%的演算法,它的做法略玄學

就是把乙個字串按asc碼用乙個進製(也叫seed,通常是131,13131)轉成乙個數字,並且使用unsigned long long自然溢位,

匹配時用小串的一部分和大串的一部分對比hs值實現匹配

**如下

1 #include2 #include3 #include4

#define n 1000055

5#define seed 13131

6using

namespace

std;

7 typedef unsigned long

long

ull;

8char

a[n],b[n];

9int

alen,blen;

10long

long

cnt;

11ull se[n],aa,abc[n];

12 inline void

init()

1323

intmain()

2431 printf("

%lld\n

",cnt);

32return0;

33 }

然後是一種絕對準確,但是會比hs慢的演算法,它叫kmp,名字取自三位大佬的名字的首字母

思想就是在失配時候不是調到頭,而是利用之前的資訊,跳到乙個更佳的位置,從而節約時間複雜度

nxt陣列的求法是演算法的精髓

1

void

getnxt()

212 }

我習慣右移一位儲存所以和網上的**不太一樣

網上很多講解,不再贅述

那裡的nxt[1]=0是最神奇的地方,用手模擬一下會發現當第一位失配時候,這麼做就可以巧妙的解決

求的時候這麼求

1

intsolvebykmp()211

return

fin;

12 }

然後就能解決,

關於nxt陣列的應用還有很多,以後的部落格中會講到

1 #include2 #include3

#define n 1000111

4#define clear(a,val) memset(a,val,sizeof(a))

5using

namespace

std;

6char

t[n],p[n];

7int

tlen,plen;

8int

nxt[n];

9void

getnxt()

1020}21

intsolvebykmp()

2231

return

fin;32}

33int

main()

34

字串匹配

題目描述 讀入資料string 然後讀入乙個短字串。要求查詢string 中和短字串的所有匹配,輸出行號 匹配字串。匹配時不區分大小寫,並且可以有乙個用中括號表示的模式匹配。如 aa 123 bb 就是說aa1bb aa2bb aa3bb都算匹配。輸入 輸入有多組資料。每組資料第一行輸入n 1 n ...

字串匹配

time limit 1000ms memory limit 65536k 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1,第二行代表string2,string1和string2中保證不出現...

字串匹配

面試題 給一串很長的字串,要求找到符合要求的字串,例如目的串 123 1 3 2 12 3 這些都要找出來 思路一 利用兩層迴圈,逐個查詢目的串中的字元,比如先查詢字元 1 是否在長字串中,再查詢 2 是否在長字串中,直到目的串遇到 0 是 include include include int m...