字符串的算法一般大公司都會(huì)考到,我們首先要想到高效的hash。
如百度查找一組字符串是否出現(xiàn)在某個(gè)文本中,這個(gè)不是考什么kmp,
他們想聽(tīng)到的是hash。趨勢(shì)科技考的是從某個(gè)文本中刪除一組字符串,
我想也是要hash吧。

1 概述
鏈表查找的時(shí)間效率為O(N),二分法為log2N,B+ Tree為log2N,但
Hash鏈表查找的時(shí)間效率為O(1)。
設(shè)計(jì)高效算法往往需要使用Hash鏈表,常數(shù)級(jí)的查找速度是任何別的
算法無(wú)法比擬的,Hash鏈表的構(gòu)造和沖突的不同實(shí)現(xiàn)方法對(duì)效率當(dāng)然
有一定的影響,然 而Hash函數(shù)是Hash鏈表最核心的部分,本文嘗試分
析一些經(jīng)典軟件中使用到的字符串Hash函數(shù)在執(zhí)行效率、離散性、空間
利用率等方面的性能問(wèn)題。

2 經(jīng)典字符串Hash函數(shù)介紹
先提一個(gè)簡(jiǎn)單的問(wèn)題,如果有一個(gè)龐大的字符串?dāng)?shù)組,然后給你一個(gè)單
獨(dú)的字符串,讓你從這個(gè)數(shù)組中查找是否有這個(gè)字符串并找到它,你會(huì)
怎么做?有一個(gè)方法最簡(jiǎn)單,老老實(shí)實(shí)從頭查到尾,一個(gè)一個(gè)比較,直
到找到為止,我想只要學(xué)過(guò)程序設(shè)計(jì)的人都能把這樣一個(gè)程序作出來(lái),
但要是有程序員把這樣的程序交給用戶,我只能用無(wú)語(yǔ)來(lái)評(píng)價(jià),或許它
真的能工作,但...也只能如此了。最合適的算法自然是使用HashTable
(哈希表),先介紹介紹其中的基本知識(shí),所謂Hash,一般是一個(gè)整數(shù),
通過(guò)某種算法,可以把一個(gè)字符串"壓縮" 成一個(gè)整數(shù),這個(gè)數(shù)稱為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);
}


                                                                                                                                                  本文經(jīng)本人整理,內(nèi)容為轉(zhuǎn)載..