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

    简单字符串hash,通过对字符串每个位置进行加权运算,使得后面每个字符的hash值都受前面字符的影响,从而将多个字节的字符串转化为整数,但有时会发生冲突。

    关键部分:seed权值,通常是质数,如果太小发生冲突的概率会大大增加。

      

    具体代码:

    typedef unsigned long long ull;
    const int maxn=40005;
    ull seed=31,ha[maxn],wei[amxn];
    
    wei[0]=1;
    for(int i=1;i<maxn;i++) wei[i]=wei[i-1]*seed;//对应长度字符串的权
    
    ha[len]=0;
    for(int i=len-1;i>=0;i--)
        ha[i]=ha[i+1]*seed+str[i]-'a';
    //求长度为l的字符串哈希值
    tmp=ha[i]-ha[i+l]*wei[l];
    
    //对字符串hash可以从左到右,也可以从右到左
                
    

      HDU4821MAP+HASH

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define N 100010
    
    unsigned long long base=31,nbase[N],hash[N];
    int n,len,ans,slen;
    char str[N];
    map<unsigned long long,int> mp;
    
    int main()
    {
        int i,j;
        unsigned long long tmp;
        nbase[0]=1;
        for(i=1;i<N;i++) nbase[i]=nbase[i-1]*base;
        while(~scanf("%d%d",&n,&len))
        {
            scanf("%s",str);
            slen=strlen(str);
            hash[slen]=0;
            for(i=slen-1;i>=0;i--)
            {
                hash[i]=hash[i+1]*base+str[i]-'a'+1;
            }
            ans=0;
            for(i=0;i<len&&i+n*len<=slen;i++)
            {
                mp.clear();
                for(j=i;j<i+n*len;j+=len)
                {
                    tmp=hash[j]-hash[j+len]*nbase[len];
                    mp[tmp]++;
                }
                if(mp.size()==n) ans++;
                for(j=i+n*len;j+len<=slen;j+=len)
                {
                    tmp=hash[j-n*len]-hash[j-(n-1)*len]*nbase[len];
                    mp[tmp]--;
                    if(mp[tmp]==0) mp.erase(tmp);
                    tmp=hash[j]-hash[j+len]*nbase[len];
                    mp[tmp]++;
                    if(mp.size()==n) ans++;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    HDU4080二分+hash

    #include <cstdio>
    #include <cstring>
    #include <map>
    using namespace std;
    typedef unsigned long long uLL ;
    const int maxn = 40050  ;
    map<uLL,int>mp;
    int pos ;
    const uLL p = 9999997 ;
    uLL powp[maxn] ;
    uLL ha[maxn] ;
    char s[maxn] ;
    
    bool check(int l , int n , int m){
        bool ok = false ;
        mp.clear();
        for(int i=1; i+l-1<=n; i++) {
            uLL tmp = ha[i+l-1] - ha[i-1] * powp[l];
            if(++mp[tmp]>=m){pos=i;ok=true;}
        }
        return ok ;
    }
    
    int main()
    {
        powp[0] = 1 ;
        for(int i=1; i<maxn; i++) powp[i] = powp[i-1] * p ;
        int m  ;
        while(scanf("%d" ,&m)==1 && m){
            scanf("%s" ,s+1) ;
            int n = strlen(s+1) ;
            ha[0] = ha[n+1] = 0 ;
            for(int i=1; i<=n;i++) ha[i] = ha[i-1]*p + s[i] ; //from end to begin ha  that's why s+1
            int L = 0 , R = n ;
            while(L<R) {
                int mid = L + (R-L+1)/2 ;
                if(check(mid , n ,m)) L = mid ;
                else R = mid - 1 ;
            }
            if(!L) puts("none") ;
            else printf("%d %d
    " , L , pos-1) ;
        }
        return 0;
    }
    View Code
    落霞与孤鹜齐飞,秋水共长天一色
  • 相关阅读:
    [leedcode 77] Combinations
    [leedcode 76] Minimum Window Substring
    [leedcode 75] Sort Colors
    [leedcode 74] Search a 2D Matrix
    [leedcode 73] Set Matrix Zeroes
    [leedcode 71] Simplify Path
    [leedcode 70] Climbing Stairs
    [leedcode 69] Sqrt(x)
    [leedcode 67] Add Binary
    HDU1027-Ignatius and the Princess II(全排列问题next_permutation函数的使用)
  • 原文地址:https://www.cnblogs.com/star-and-me/p/6806118.html
Copyright © 2011-2022 走看看