zoukankan      html  css  js  c++  java
  • hash相关理论

    将网上和课件的hash做个小结 

    1、解决冲突是hash表的关键,冲突越少,hash表的效率越高

    2、设计hash函数方法,分别介绍整数和字符串的hash函数

    一、整数的hash函数 

    (1)最常见的是直接取余数法,h(k)=k mod M,M表示hash表的容量,此处应注意M的选取,M若选不好,很容易出现同义词。一般情况下,可以选M为素数或者不包含小于20的质因数的合数。

     (2)平方取中法,对关键字k平方,中间几位数k的每一位的影响最大,把关键字k平方后,取出中间r位作为哈希函数h(k)的值,这时需要容量M=2的r次方,一般情况是将关键字转化为二进制,平方后取中间r位作为哈希地址即h(k)

    例如:r=4,k=100 

    k=(1100100)(二进制表示) 

    k平方 =(10010 1000 10000)(二进制表示)

    h(k)=(1000)(二进制表示)=8

     (3)利用无理数,用关键字k乘以(0,1)之间的一个无理数A,然后取出小数部分,乘以M,再取出整数部分作为哈希地址

    例如 k=100,A=0.,587778,M=20,则h(k)= 15

    比较三种优劣:

    直接取余法:实现容易,效果手M影响大

    平方取中发:速度快,不易推广

    乘积取整法:M可以任意选取,效果好,速度慢

    因此,在一般情况下,选取第一种就行了 

     二、字符串的hash函数

     (1)字符串一般比较长,无法实现直接定址

     (2) 由于字符串在计算机中是以二进制形式存在,可以将字符串看做256进制的大整数,利用整数中直接取余法

     (3)BKDRhash函数

    // BKDR Hash Function
    unsigned int BKDRHash(char *str)
    {
    unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
    unsigned int hash = 0;

    while (*str)
    {
        hash = hash * seed + (*str++);
    }

    return (hash & 0x7FFFFFFF);
    }

     (4)SDBMhash函数

    unsigned int SDBMHash(char *str)
    {
    unsigned int hash = 0;

    while (*str)
    {
    // equivalent to: hash = 65599*hash + (*str++);
    hash = (*str++) + (hash << 6) + (hash << 16) - hash;
    }

    return (hash & 0x7FFFFFFF);
    }

     

  • 相关阅读:
    BZOJ4849[Neerc2016]Mole Tunnels——模拟费用流+树形DP
    BZOJ3638[Codeforces280D]k-Maximum Subsequence Sum&BZOJ3272Zgg吃东西&BZOJ3267KC采花——模拟费用流+线段树
    BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流
    BZOJ2151种树——模拟费用流+链表+堆
    CF1117D Magic Gems
    CF1117C Magic Ship
    CF1117A Best Subsegment
    Loj 2028 随机序列
    Loj 504 ZQC的手办
    Luogu 3806 点分治1
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2165890.html
Copyright © 2011-2022 走看看