字符串的算法一般大公司都會考到,我們首先要想到高效的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);
}


                                                                                                                                                  本文經本人整理,內容為轉載..