zoukankan      html  css  js  c++  java
  • 洛谷 P3370 【模板】字符串哈希

    P3370 【模板】字符串哈希

    字符串哈希就是根据一个字符串s通过某种方法计算得到一个数字x,这样如果字符串s对应一个值y的话,可以把y保存在数组a[x]中,这样如果告诉你字符串,要得到或者修改对应的值,就比较方便。

    因为这个数字通常有大小限制,字符串却是无限的,所以哈希通常会有冲突,也就是多个不同的串计算出相同的数字。

    因此,哈希算法需要某些措施来减少冲突的可能,例如使算法更复杂,对同一个串多算几个数字等。

    但也不是冲突越少越好的,因为减少冲突必然伴随着运算量的增加(还有编程复杂度的增加)。不可能为了使冲突消失就每次用哈希都写很长代码。因此,对于不同题目可以不同选择,比如单哈希,双哈希,甚至只对某几个位置哈希,还有几个有名的哈希算法等等。

    大质数(可以用来换掉文中1000000007和1000000009):

    33951943,10007,1313331

    另外,1000000007和1000000009慎用,会被针对。(吃瓜群众:那你还用?我:其实多乘了个31或29之后也不要紧吧。。)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct Hasha
    {
        int a,b;
    }hasha[11000];
    char s[1600];
    bool cmp(Hasha a,Hasha b)
    {
        return a.a<b.a;
    }
    int ans,n,num;
    void hashx(char s[])
    {
        int i,hash1=0,hash2=0,len=strlen(s);
        for(i=0;i<len;i++)
        {
            hash1=(hash1*31+s[i])%1000000007;//一种非常简单的哈希,可以简单的通过更改31还有1000000007来修改同一个字串对应的结果
            hash2=(hash2*29+s[i])%1000000009;//对于每个字符串,计算出两个值
        }
        hasha[++num].a=hash1;
        hasha[num].b=hash2;
    }
    int main()
    {
        int i;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%s",s);
            hashx(s);
        }
        sort(hasha+1,hasha+n+1,cmp);
        for(i=1;i<num;i++)
            if(hasha[i].a==hasha[i+1].a&&hasha[i].b==hasha[i+1].b)//如果两个串计算出的两个值分别相等,就认为串本身也是相等的(但是仍然存在被卡掉的可能,也就是串本身不相等计算出来两个值分别相等,但这道题没有)
                ans++;
        printf("%d",n-ans);
        return 0;
    }


  • 相关阅读:
    NEON中的L可以避免溢出
    编译Qualcomm的Hexagon exampls错误
    C语言中的static
    在非NDK编译条件下使用Android Log函数
    NEON的vsub方法溢出
    OpenCL中读取image时的坐标
    Ubuntu16.0 GTX1660Ti 安装NVIDIA CUDA cuDNN Tensflow
    修改so库中的依赖名
    Qt数据库总结
    Qt插件系统
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8470454.html
Copyright © 2011-2022 走看看