zoukankan      html  css  js  c++  java
  • hash入门

    只讨论最常用的进制哈希。

    例题

    洛谷P3370

    题意:求 N 个字符串中有多少个不同的字符串($N leq 10^4$)。

    分析:

    对每个字符串求一次哈希值,然后统计有多少个不同的哈希值。

    单哈希

    选择一个大质数,或者自然溢出。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    const ull base = 233;
    ull mod=212370440130137957ll;
    const int maxn = 10000+10;
    int n;
    ull f[maxn];
    char s[maxn];
    
    ull Hash(char s[])  //自然溢出
    {
        ull ans = 0;
        int len = strlen(s);
        for(int i = 0;i < len;i++)
        {
            ans = (base*ans + (ull)s[i]) % mod;
        }
        return ans;
    }
    
    set<ull>st;
    int main()
    {
        scanf("%d", &n);
        for(int i = 0;i < n;i++)
        {
            scanf("%s", s);
            st.insert(Hash(s));
        }
        printf("%d
    ", st.size());
    }

    双哈希

    采用两个模数,哈希冲突的概率会降低很多,但常数会增大。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    const ull base = 233;
    ull mod1 = 212370440130137957ll;
    ull mod2 = 1 << 30;
    const int maxn = 10000+10;
    int n;
    char s[maxn];
    
    ull Hash1(char s[])  //自然溢出
    {
        ull ans = 0;
        int len = strlen(s);
        for(int i = 0;i < len;i++)
        {
            ans = (base*ans + (ull)s[i]) % mod1;
        }
        return ans;
    }
    ull Hash2(char s[])  //自然溢出
    {
        ull ans = 0;
        int len = strlen(s);
        for(int i = 0;i < len;i++)
        {
            ans = (base*ans + (ull)s[i]) % mod2;
        }
        return ans;
    }
    
    struct Node{
        ull x, y;
    }f[maxn];
    bool cmp(Node a, Node b)
    {
        if(a.x == b.x)  return a.y < b.y;
        return a.x < b.x;
    }
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 0;i < n;i++)
        {
            scanf("%s", s);
            f[i].x = Hash1(s);
            f[i].y = Hash2(s);
            //printf("%lld %lld
    ", f[i].x, f[i].y);
        }
        sort(f, f+n, cmp);
        int cnt  = 1;
        for(int i = 0;i < n-1;i++)
        {
            if(f[i+1].x != f[i].x || f[i+1].y != f[i].y)  cnt++;
        }
        printf("%d
    ", cnt);
    }

    参考链接:https://www.cnblogs.com/henry-1202/p/8868414.html

  • 相关阅读:
    从高版本JDK换成低版本JDK报错Unsupported major.minor version 52.0
    永远不要祈求生活来怜悯你,你只能让自己变的更强
    69 个经典 Spring 面试题和答案
    Jackson 框架,轻易转换JSON
    Apache Commons Codec 编码解码
    演讲
    Shiro源码分析-初始化-Realm
    各个JSON技术的比较
    常见数据库设计(2)——历史数据问题之单记录变更
    fiddler
  • 原文地址:https://www.cnblogs.com/lfri/p/11375253.html
Copyright © 2011-2022 走看看