字符串的算法一般大公司都会考到,我们首先要想到高效的hash。
如百度查找一组字符串是否出现在某个文本中,这个不是考什么kmp,
他们想听到的是hash。趋势科技考的是从某个文本中删除一组字符串,
我想也是要hash吧。

1 概述
链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但
Hash链表查找的时间效率为O(1)。
设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的
算法无法比拟的,Hash链表的构造和冲突的不同实现方法对效率当然
有一定的影响,然 而Hash函数是Hash链表最核心的部分,本文尝试分
析一些经典软件中使用到的字符串Hash函数在执行效率、离散性、空间
利用率等方面的性能问题。

2 经典字符串Hash函数介绍
先提一个简单的问题,如果有一个庞大的字符串数组,然后给你一个单
独的字符串,让你从这个数组中查找是否有这个字符串并找到它,你会
怎么做?有一个方法最简单,老老实实从头查到尾,一个一个比较,直
到找到为止,我想只要学过程序设计的人都能把这样一个程序作出来,
但要是有程序员把这样的程序交给用户,我只能用无语来评价,或许它
真的能工作,但...也只能如此了。最合适的算法自然是使用HashTable
(哈希表),先介绍介绍其中的基本知识,所谓Hash,一般是一个整数,
通过某种算法,可以把一个字符串"压缩" 成一个整数,这个数称为Hash.

 

//RSHash
inline unsigned int RSHash(char* str)
{
    unsigned 
int b = 50021;
    unsigned 
int a = 7003;
    unsigned 
int hash = 0;

    
while (*str)
    
{
        hash 
= hash * a + (*str++);
        a 
*= b;
    }


    
return (hash & 0x7FFFFFFF);
}
 


//ELFHash
inline unsigned int ELFHash(char* str)
{
    unsigned 
int hash = 0;
    unsigned 
int x    = 0;

    
while (*str)
    
{
        hash 
= (hash << 4+ (*str++);
        
if ((x = hash & 0xF0000000L!= 0)
        
{
            hash 
^= (x >> 24);
            hash 
&= ~x;
        }

    }


    
return (hash & 0x7FFFFFFF);
}


//JSHash
inline unsigned int JSHash(char* str)
{
    unsigned 
int hash = 1315423911;

    
while (*str)
    
{
        hash 
^= ((hash << 5+ (*str+++ (hash >> 2));
    }


    
return (hash & 0x7FFFFFFF);
}


//PJWHash
inline unsigned int PJWHash(char* str)
{
    unsigned 
int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int* 8);
    unsigned 
int ThreeQuarters    = (unsigned int)((BitsInUnignedInt * 3/ 4);
    unsigned 
int OneEighth        = (unsigned int)(BitsInUnignedInt / 8);

    unsigned 
int HighBits         = (unsigned int)(0xFFFFFFFF<< (BitsInUnignedInt - OneEighth);
    unsigned 
int hash             = 0;
    unsigned 
int test             = 0;

    
while (*str)
    
{
        hash 
= (hash << OneEighth) + (*str++);
        
if ((test = hash & HighBits) != 0)
        
{
            hash 
= ((hash ^ (test >> ThreeQuarters)) & (~HighBits));
        }

    }


    
return (hash & 0x7FFFFFFF);
}
 

//BKDRHash
inline unsigned int BKDRHash(char* str)
{
    unsigned 
int seed = 131;  
    unsigned 
int hash = 0;

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


    
return (hash & 0x7FFFFFFF);
}


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

    
while (*str)
    
{
        hash 
= (*str+++ (hash << 6+ (hash << 16- hash;
    }


    
return (hash & 0x7FFFFFFF);
}


//DJBHash
inline unsigned int DJBHash(char* str)
{
    unsigned 
int hash = 5381;

    
while (*str)
    
{
        hash 
+= (hash << 5+ (*str++);
    }


    
return (hash & 0x7FFFFFFF);
}


//APHash
inline unsigned int APHash(char* str)
{
    unsigned 
int hash = 0;
    
int i;

    
for (i = 0*str; i++)
    
{
        
if ((i & 1== 0)
        
{
            hash 
^= ((hash << 7^ (*str++^ (hash >> 3));
        }

        
else
        
{
            hash 
^= (~((hash << 11^ (*str++^ (hash >> 5)));
        }

    }


    
return (hash & 0x7FFFFFFF);
}


                                                                                                                                                  本文经本人整理,内容为转载..