1. 程式人生 > >「LOJ#103」子串查找 (Hash

「LOJ#103」子串查找 (Hash

ott 表示 pre lock -s 出現 提示 ica turn

題目描述

這是一道模板題。

給定一個字符串 A A A 和一個字符串 B B B,求 B B B 在 A A A 中的出現次數。AAA 和 BBB 中的字符均為英語大寫字母或小寫字母。

A A A 中不同位置出現的 B B B 可重疊。

輸入格式

輸入共兩行,分別是字符串 A A A 和字符串 B B B。

輸出格式

輸出一個整數,表示 B B B 在 A A A 中的出現次數。

樣例

樣例輸入

zyzyzyz
zyz

樣例輸出

3

數據範圍與提示

1≤A,B 1 \leq A, B1A,B 的長度 ≤106 \leq 10 ^ 6 106,A A A、B B B 僅包含大小寫字母。

題解

題目說了是道KMP模板題qwq

 1 /*
 2 編號     題目     狀態     分數     總時間     內存     代碼 / 答案文件     提交者     提交時間
 3 #224544     #103. 子串查找    Accepted     100     550 ms     2228 KiB     C++ / 545 B     qwerta     2018-10-10 18:01:15
4 */ 5 #include<iostream> 6 #include<cstdio> 7 using namespace std; 8 int nxt[1000003]; 9 int main() 10 { 11 string s,t; 12 cin>>s>>t; 13 int k=-1; 14 nxt[0]=-1; 15 int lens=s.length(),lent=t.length(); 16 for(int i=1;i<lent;++i) 17 {
18 while(k!=-1&&t[i]!=t[k+1])k=nxt[k]; 19 if(t[i]==t[k+1])k++; 20 nxt[i]=k; 21 } 22 k=-1; 23 int ans=0; 24 for(int i=0;i<lens;++i) 25 { 26 while(k!=-1&&s[i]!=t[k+1])k=nxt[k]; 27 if(s[i]==t[k+1])k++; 28 if(k==lent-1){ans++;} 29 } 30 cout<<ans; 31 return 0; 32 }

然後還用來給Hash練了手(Hash首A!

/*
編號     題目     狀態     分數     總時間     內存     代碼 / 答案文件     提交者     提交時間
#224464     #103. 子串查找    Accepted     100     589 ms     2228 KiB     C++ / 817 B     qwerta     2018-10-10 17:06:38
*/
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    //freopen("a.in","r",stdin);
    string a,b;
    cin>>a>>b;
    unsigned long long h=0,hb=0;
    int lena=a.length(),lenb=b.length();
    int mod=19260817,p=233;//膜數(bi~)
    //
    unsigned long long pown=1,base=p;
    int k=lenb-1;
    while(k)
    {
        if(k&1)
        pown=pown*base%mod;
        base=base*base%mod;
        k>>=1;
    }
    //
    for(int i=0;i<lenb;++i)
    hb=(hb*p+b[i])%mod;
    for(int i=0;i<lenb;++i)
    h=(h*p+a[i])%mod;
    int ans=0;
    if(hb==h)ans++;
    //cout<<h<<" "<<hb<<endl;
    for(int i=lenb;i<lena;++i)
    {
        h-=a[i-lenb]*pown%mod;
        h=((h+mod)*p+a[i])%mod;
        //cout<<h<<" "<<hb<<endl;
        if(h==hb)ans++;
    }
    cout<<ans;
    return 0;
}

這是個什麽笨重代碼啊(自我吐槽

「LOJ#103」子串查找 (Hash