zoukankan      html  css  js  c++  java
  • 字符串HASH模板

    //注意MAXN是最大不同的HASH个数,一般HASHN是MAXN的两倍左右,MAXLEN表示字符串的最大长度
    //K表示正确率,越大正确率越高,当时也越费空间,费时间。
    //使用前注意初始化hash_init();
    //用法参考下面注释程序。
    //HashNode里面可以储存很多信息,注意灵活使用。 内存如果可能溢出可修改使得内存减一半,但是注意乘法溢出。
    #define HASHN 1000007
    #define MAXN 500000
    #define MAXLEN 500500
    #define K 2
    
    typedef unsigned long long ull;
    typedef unsigned int ui;
    struct HashNode
    {
        int next;
        ull key[K];//关键点
    }hashnode[MAXN];
    
    const ull mod[3]={ 2147483647U, 2147483629U, 2147483587U };
    const ull seed[3]={ 131U, 10007U, 4243U};
    int hashpre[ HASHN ],hashcnt;
    
    
    void hash_init()
    {
        hashcnt=0;
        memset(hashpre,-1,sizeof(hashpre));
    }
    
    bool hash_find(ull key[K])
    {
        int hashkey=0;
        for(int i=0;i<K;i++)
            hashkey += (key[i])%HASHN;
        hashkey %= HASHN;
        ull nkey[K];
        for(int p=hashpre[hashkey];p!=-1;p=hashnode[p].next)
        {
            for(int i=0;i<K;i++) nkey[i] = hashnode[p].key[i];
            bool nsign=0;
            for(int i=0;i<K;i++)
            {
                if(key[i] != nkey[i])
                {
                    nsign=1;
                    break;
                }
            }
            if(nsign==0) return true;
        }
        return false;
    }
    
    void hash_insert(ull key[K])
    {
        int hashkey=0;
        for(int i=0;i<K;i++)
            hashkey += (key[i])%HASHN;
        hashkey %= HASHN;
        
        if( hash_find(key) ) return ;//hash表中已经存在
        
        //不存在使用头插入法,插入新节点。
        for(int i=0;i<K;i++)
            hashnode[hashcnt].key[i] = key[i];
        hashnode[hashcnt].next = hashpre[hashkey];
        hashpre[ hashkey ] = hashcnt++;
    }
    
    void hash_getkey(char *str,int len,ull key[K])
    {
        ull tmp=1;
        for(int i=0;i<K;i++)
        {
            key[i] = 0;
            tmp = 1;
            for(int j=0;j<len;j++)
            {
                key[i] = ( key[i]+tmp*str[j] )%mod[i];
                tmp *= seed[i];
                tmp %= mod[i];
            }
        }
        return ;
    }
    
    void hash_insert(char *str,int len)
    {
        ull key[K];
        hash_getkey(str,len,key);
        hash_insert(key);
    }
    
    bool hash_find(char *str,int len)
    {
        ull key[K];
        hash_getkey(str,len,key);
        return hash_find(key);
    }
    
    void hash_getpow(int len,ull hashpow[][MAXLEN])
    {
        ull tmp=1;
        for(int i=0;i<K;i++)
        {
            tmp=1;
            for(int j=0;j<len;j++)
            {
                hashpow[i][j] = tmp;
                tmp *= seed[i];
                tmp %= mod[i];
            }
        }
    }
    
    void hash_getsuffix(char *str,int len,ull hashsuf[][MAXLEN])
    {
        ull tmp=1;
        for(int i=0;i<K;i++)
        {
            tmp=1;
            for(int j=0;j<len;j++)
            {
                hashsuf[i][j] = (tmp*str[j])%mod[i];
                tmp *= seed[i];
                tmp %= mod[i];
            }
            hashsuf[i][len]=0;
            for(int j=len-1;j>=0;j--)
            {
                hashsuf[i][j] += hashsuf[i][j+1];
                if( hashsuf[i][j]>=mod[i] ) hashsuf[i][j] -= mod[i];
            }
        }
    }
    
    void hash_getprefix(char *str,int len,ull hashpref[][MAXLEN])
    {
        ull tmp=1;
        for(int i=0;i<K;i++)
        {
            hashpref[i][0] = str[0];
            tmp = seed[i];
            for(int j=1;j<len;j++)
            {
                hashpref[i][j] = hashpref[i][j-1]+(tmp*str[j])%mod[i];
                if( hashpref[i][j]>=mod[i] ) hashpref[i][j] -= mod[i];
                tmp *= seed[i];
                tmp %= mod[i];
            }
        }
    }
    
    /*
    char str[1001000];
    ull hashpow[K][MAXLEN],hashpref[K][MAXLEN],hashsuf[K][MAXLEN];
    
    int main() {
        int n,m;
        scanf("%d%d",&n,&m);
        
        hash_init();//第一步初始化
        
        for(int i=0;i<n;i++)
        {
            scanf("%s",str);
            int len=strlen(str);
            hash_insert(str,len);//插入hash表
        }
        
        hash_getpow(MAXLEN, hashpow);//得到pow
        
        for(int i=0;i<m;i++)
        {
            scanf("%s",str);
            int len=strlen(str);
            int flag=0;
            
            hash_getprefix(str, len, hashpref);//得到前缀和
            hash_getsuffix(str, len, hashsuf);//得到后缀和
            
            //具体情况,具体操作。
            for(int j=0;j<len;j++)
            {
                for(int k='a';k<='c';k++)
                {
                    if(k==str[j]) continue;
                    
                    ull key[K];
                    for(int p=0;p<K;p++)
                    {
                        key[p] =( (j>0?hashpref[p][j-1]:0) + hashpow[p][j]*k%mod[p]+hashsuf[p][j+1])%mod[p];
                        while(key[p]>=mod[p]) key[p] -= mod[p];
                    }
                    if( hash_find(key) )
                    {
                        flag=1;
                        break;
                    }
                }
                if(flag) break;
            }
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    
    */
  • 相关阅读:
    7月15日考试 题解(链表+状压DP+思维题)
    暑假集训日记
    C# .NET 使用 NPOI 生成 .xlsx 格式 Excel
    JavaSE 基础 第42节 局部内部类
    JavaSE 基础 第41节 匿名内部类
    JavaSE 基础 第40节 内部类概述
    JavaSE 基础 第39节 接口的应用
    JavaSE 基础 第38节 接口的实现
    JavaSE 基础 第37节 接口概述
    JavaSE 基础 第36节 抽象类概述与使用
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5121812.html
Copyright © 2011-2022 走看看