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;
    }
    
    */
  • 相关阅读:
    vue-cli webpack3扩展多模块打包
    性能对比:aelf智能合约运行环境性能是evm的1000倍
    aelf帮助C#工程师10分钟零门槛搭建DAPP&私有链开发环境
    ASP.NET Core依赖注入最佳实践,提示&技巧
    linux环境安装php fileinfo扩展
    简单的部署nodejs和web应用
    安卓NDK操作sqlite3
    [解决]微信小程序调用wx.login解密之后出现乱码的问题
    windows server 2008 iis 添加ssl证书
    Mac 下修改文件或文件夹的隐藏状态
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5121812.html
Copyright © 2011-2022 走看看