zoukankan      html  css  js  c++  java
  • 字符串哈希hash

    题目描述

    如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。

    友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)

    输入输出格式

    输入格式:

    第一行包含一个整数N,为字符串的个数。

    接下来N行每行包含一个字符串,为所提供的字符串。

    输出格式:

    输出包含一行,包含一个整数,为不同的字符串个数。

    输入输出样例

    输入样例#1:
    5
    abc
    aaaa
    abc
    abcc
    12345
    输出样例#1:
    4

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=10,Mi≈6,Mmax<=15;

    对于70%的数据:N<=1000,Mi≈100,Mmax<=150

    对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500

    样例说明:

    样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。

    Tip: 感兴趣的话,你们可以先看一看以下三题:

    BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

    BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

    BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

    如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的^_^

    字符串hash,把每一位当做一个某进制大数的一位,乘积后mod一个素数 

    在此讲解三种姿势

    1.ull自然溢出

    100分

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 101010;
    typedef unsigned long long ull; 
    int hash[maxn];
    int base=131;
    char s[maxn];
    
    int n,ans=1;
    ull h(char *s) {
        int len =strlen(s);
        ull ans=0;
        for(int i=0;i<len;++i)
            ans=ans*(ull)base+(ull)s[i];
        return ans&0x7fffffff;
    }
    int main () {
        scanf("%d",&n);
        for(int i=1;i<=n;++i) {
            scanf("%s",s);
            hash[i]=h(s);
        }
        sort(hash+1,hash+n+1);
        for(int i=2;i<=n;++i)
          if(hash[i]!=hash[i-1])
                ans++;
        printf("%d
    ",ans);
        return 0;
    }

    2.对单素数取mod

    70分

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 101010;
    typedef unsigned long long ull; 
    ull mod = 20020711;
    int hash[maxn];
    int base=131;
    char s[maxn];
    
    int n,ans=1;
    ull h(char *s) {
        int len =strlen(s);
        ull ans=0;
        for(int i=0;i<len;++i)
            ans=(ans*(ull)base+(ull)s[i])%mod;
        return ans;
    }
    int main () {
        scanf("%d",&n);
        for(int i=1;i<=n;++i) {
            scanf("%s",s);
            hash[i]=h(s);
        }
        sort(hash+1,hash+n+1);
        for(int i=2;i<=n;++i)
          if(hash[i]!=hash[i-1])
                ans++;
        printf("%d
    ",ans);
        return 0;
    }

    对双素数取mod

    100分

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 101010;
    typedef unsigned long long ull; 
    const int  mod1 = 20020711;
    const int  mod2 = 19260817;
    struct data{
        int x, y;
        bool operator < (const data &a)const {
            return x< a.x;
        }
    }hash[maxn];
    int base=131;
    char s[maxn];
    
    int n,ans=1;
    int h1(char *s) {
        int len =strlen(s);
        int ans=0;
        for(int i=0;i<len;++i)
            ans=(ans*base+s[i])%mod1;
        return ans;
    }
    int h2(char *s) {
        int len =strlen (s);
        int ans=0;
        for(int i=0;i<len;++i)
            ans=(ans*base+s[i])%mod2;
        return ans;
    }
    int main () {
        scanf("%d",&n);
        for(int i=1;i<=n;++i) {
            scanf("%s",s);
            hash[i].x=h1(s);
            hash[i].y=h2(s);
        }
        sort(hash+1,hash+n+1);
        for(int i=2;i<=n;++i)
          if(hash[i].x!=hash[i-1].x||hash[i].y!=hash[i-1].y)
                ans++;
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Java vs Python
    Compiled Language vs Scripting Language
    445. Add Two Numbers II
    213. House Robber II
    198. House Robber
    276. Paint Fence
    77. Combinations
    54. Spiral Matrix
    82. Remove Duplicates from Sorted List II
    80. Remove Duplicates from Sorted Array II
  • 原文地址:https://www.cnblogs.com/sssy/p/7674414.html
Copyright © 2011-2022 走看看