PHP核心技術與最佳實務之Hash演算法

來源:互聯網
上載者:User

標籤:hash   php核心技術與最佳實務之hash演算法   

PHP核心技術與最佳實務之Hash演算法

Hash表又稱散列表,通過把關鍵字Key映射到數組中的一個位置來訪問記錄,以加快尋找速度。這個映射函數稱為Hash函數,存放記錄的數組稱為Hash表。

1.     Hash函數

作用是把任意長度的輸入,通過Hash演算法變換成固定長度的輸出,該輸出就是Hash值。這種轉換是一種壓縮映射,也就是Hash值得空間通常遠小於輸入的空間,不輸入可能會散列成相同的輸出,而不可能從Hash值來唯一的確定輸入值。

一個好的hash函數應該滿足以下條件:每個關鍵字都可以均勻的分布到Hash表任意一個位置,並與其他已被散列到Hash表中的關鍵字不發生衝突。這是Hash函數最難實現的。

2.     Hash演算法

1)    直接取餘法

直接取餘法比較簡單,直接用關鍵字k除以Hash表的大小m取餘數,演算法如下:

H(k) = k mod m

例如:Hash表的大小為m=12,所給關鍵字為k=100,則h(k) = 4.這種演算法是一個求餘操作,速度比較快。

2)    乘積取整法

乘積取整法首先使用關鍵字k乘以一個常數A(0<A<1),並抽取kA的小數部分,然後用Hash表大小m乘以這個值,再取整數部分即可。演算法如下:

H(k) = floor (m*(kA mod 1))

其中,kA mod1表示kA的小數部分,floor是取整操作。

當關鍵字是字串的時候,就不能用上面的Hash演算法。因為字串是由字元組成,所以可以把字串所有的字元的ASCII碼加起來得到一個整數,然後再按照上面的Hash演算法去計算即可。

演算法如下:

Function hash($key,$m){

         $strlen= strlen($key);

         $hashval= 0;

         For($i=0;$i< $strlen;$i++){

       $hashval+=ord($key{$I});

}

Return $hashval % $m;

}

3)    經典Hash演算法Times33

Unsigned int DJBHash(char *str){

         Unsignedint hash = 5381;

         While(*str){

       Hash+=(hash <<5)+(*str++);

}

Return (hash &0x7FFFFFFF)

}

演算法思路就是不斷乘以33,其效率和隨機性都非常好,廣泛運用於多個開源項目中,如Apache、Perl和PHP等。

3.     Hash表

Hash表的時間複雜度為O(1),Hash表結構可用圖表示:



要構造一個Hash表必須建立一個足夠大的數組用於存放資料,另外還需要一個Hash函數把關鍵字Key映射到數組的某個位置。

Hash表的實現步驟:

1)    建立一個固定大小的數組用於存放資料。

2)    設計Hash函數。

3)    通過Hash函數把關鍵字映射到數組的某個位置,並在此位置上進行資料存取。

4.     使用PHP實現Hash表

首先建立一個HashTable類,有兩個屬性$buckets和$size。$buckets用於儲存資料的數組,$size用於記錄$buckets數組大小。然後在建構函式中為$buckets數組分配記憶體。代碼如下:

<?PHP

        ClassHashTable{

               Private$buckets;

               Private$size =10;

               Publicfunction __construct(){

              $this-> buckets =new SplFixedArray($this->size);

}

}

?>

在建構函式中,為$buckets數組分配了一個大小為10的數組。在這裡使用了SPL擴充的SplFixedArray數組,不是一般的數組(array)

這是因為SplFixedArray數組更接近於C語言的數組,而且效率更高。在建立其數組時需要為其提供一個初始化的大小。

注意:要使用SplFixedArray數組必須開啟SPl擴充。如果沒有開啟,可以使用一般的數組代替。

接著為Hash表指定一個Hash函數,為了簡單起見,這裡使用最簡單的Hash演算法。也就是上面提到了把字串的所有字元加起來再取餘。代碼如下:

 

 

 

Public Function hashfunc($key){

         $strlen= strlen($key);

         $hashval= 0;

         For($i=0;$i< $strlen;$i++){

       $hashval+=ord($key{$I});

}

Return $hashval % $this->size;

}

有了Hash函數,就可以實現插入和尋找方法。插入資料時,先通過HashFunction Compute關鍵字所在Hash表的位置,然後把資料儲存到此位置即可。代碼如下:

Public function insert($key,$val){

        $index= $this -> hashfunc($key);

        $this-> buckets[$index] = $val;

}

尋找資料方法與插入資料方法相似,先通過HashFunction Compute關鍵字所在Hash表的位置,然後返回此位置的資料即可。代碼如下:

Public function find($key){

        $index= $this -> hashfunc($key);

        Return$this ->buckets[$index];

}

至此,一個簡單的Hash表編寫完成,下面測試這個Hash表。代碼清單如下:

<?PHP

        $ht= new HashTable();

        $ht->insert(‘key1’,’value1’);

        $ht->insert(‘key2’,’value2’);

        Echo$ht ->find(‘key1’);

        Echo$ht ->find(‘key2’);

?>

完整代碼:#hash.php

<?PHP             Class HashTable{                    Private$buckets;                    Private $size=10;                    Public function__construct(){                           $this-> buckets =new SplFixedArray($this->size);                    }                    PublicFunction hashfunc($key){                           $strlen= strlen($key);                           $hashval= 0;                           For($i=0;$i< $strlen;$i++){                                  $hashval+=ord($key{$i});                           }                           return$hashval % $this->size;                    }                    Publicfunction insert($key,$val){                           $index= $this -> hashfunc($key);                           $this-> buckets[$index] = $val;                    }                    Publicfunction find($key){                           $index= $this -> hashfunc($key);                           Return$this ->buckets[$index];                    }               }             $ht = newHashTable();             $ht->insert('key1','value1');             $ht->insert('key2','value2');             Echo $ht->find('key1');             Echo $ht->find('key2'); ?>


PHP核心技術與最佳實務之Hash演算法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.