「LOJ#103」子串查找 (Hash

「LOJ#103」子串查找 (Hash

题目描述

这是一道模板题。

给定一个字符串 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;
}

这是个什么笨重代码啊(自我吐槽