Wannafly挑戰賽11_D_白兔的字符串(字符串hash)

傳送門

思路:字符串hash。對於原串,我們進行Hash,存入unordered_set。在O(n)的時間內就可以將所有的Hash值都算出來。
對於接下來的n串。我們對於每一串我們只需要掃描一邊,看Hash值是否在unordered_set中計數即可。
深深感受到unordered_set 和set的區別。
這裏寫圖片描述
這是set超時!!
對於這兩個STL。

map的優點:有序。題目如果要求對於有序的查詢會更加有利。但是時間相比較unordered_set會慢一些。

unordered_set 的優點:unordered_set作爲c++11的新特性,有點還是特別的突出的。因爲內部實現了哈希表,因此其查找速度非常的快。在這道題目中非常明顯的展現了出來。而其缺點就是無序。

#include<bits/stdc++.h>
#define debug(a) cout << #a << " " << a << endl
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-6
const int N=1e6+7;
const int base=233;
using namespace std;
unordered_set<ull> s;
char s1[N],s2[N];
ull p[N];
int len_a,len_b;
void init()
{
    len_a=strlen(s1+1);
    ull Hash=0;
    p[0]=1;
    for(int i=1;i<=len_a;i++){
        Hash=Hash*base+s1[i]-'0';
        p[i]=p[i-1]*base;
    }
    s.insert(Hash);
    for(int i=1;i<=len_a;i++){
        Hash=(Hash-(s1[i]-'0')*p[len_a-1])*base+s1[i]-'0';
        s.insert(Hash);
    }
}
int main ()
{
    //yyy_3y
    //freopen("1.in","r",stdin);
    scanf("%s",s1+1);
    init();
    int n; scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s2+1);

        len_b=strlen(s2+1);
        ull Hash=0;
        ull ans=0;
        for(int i=1;i<=len_a;i++){
            Hash=Hash*base+s2[i]-'0';
        }
        if(s.count(Hash)) ans++;
        for(int i=len_a+1;i<=len_b;i++){
             Hash=(Hash-(s2[i-len_a]-'0')*p[len_a-1])*base+s2[i]-'0';
             if(s.count(Hash)) ans++;
        }
        printf("%llu\n",ans);
    }
    return 0;
}
/*
abab
2
ababcbaba
*/
發佈了82 篇原創文章 · 獲贊 8 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章