[C++]Hashクラス・改訂版,

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

かなり前に書いたハッシュのクラスファイル(http://yamablo.com/2008/11/14-005442.php)の訂正版になります。訂正版を公開するのを忘れてました。

想定は、2項目からなるデータをハッシュとして保持する状況を考えてます。2項目のうち1つはキーとなる項目で、残りの1項目は非キー項目です。

Hash.cpp

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define     DATA_SIZE   256 
  5. #define     TABLE_SIZE  200
  6. // ハッシュ表に格納するデータの構造
  7. typedef struct data {
  8.     char    key[DATA_SIZE];       // 格納するキーのデータ
  9.     char    value[DATA_SIZE];     // 格納する非キーのデータ
  10.     int     flg;                  // 格納状態のフラグ
  11. } data;
  12. class Hash {
  13.     public:
  14.         data    HashTable[TABLE_SIZE];  // ハッシュ表
  15.         int     collision;              // データ格納時にコリジョンが発生した回数
  16.         int     stored;                 // データの格納数
  17.         double  StoredPerAll;           // データの格納率
  18.     private:
  19.         // ハッシュ値を求める
  20.         int HashValue( char *str ) {
  21.             int     idx;        // インデックスカウンタ
  22.             int     length;     // 文字列の長さを格納
  23.             int     h = 0;      // ハッシュ値を格納
  24.             length = strlen( str );
  25.             for( idx=0; idx<length; idx++ ) {
  26.                 h = h * 37 + str[idx];
  27.             }
  28.             h = h % TABLE_SIZE;
  29.             return abs(h);
  30.         }
  31.     public:
  32.         /* ******************************************
  33.          * データstrの格納場所を求める
  34.          * もし存在しなければ、-1を返す
  35.          * ****************************************** */
  36.         int where( char *str ) {
  37.             int         h;
  38.             h = this->HashValue( str );
  39.             // 該当場所のデータが空で、削除もしていないとき
  40.             if( this->HashTable[h].flg == 0 ) {
  41.                 return -1;
  42.             }
  43.             // ハッシュ表の該当場所をチェックし、
  44.             // その場所から目的のデータを探す
  45.             while( strcmp(this->HashTable[h].key, str)!=0 ) {
  46.                 h++;
  47.                 if( h == TABLE_SIZE ) {
  48.                     h = 0;
  49.                 } else if( h == this->HashValue( str ) ) {
  50.                     // ハッシュ表を全て見てもなかった場合、Not Found
  51.                     return -1;
  52.                 }
  53.             }
  54.             return      h;
  55.         }
  56.         // コンストラクタ
  57.         Hash() {
  58.             int idx;
  59.             for( idx=0; idx<TABLE_SIZE; idx++ ) {
  60.                 this->HashTable[idx].key[0] = ’\0′;
  61.                 this->HashTable[idx].value[0] = ’\0′;
  62.                 this->HashTable[idx].flg = 0;
  63.             }
  64.             this->collision = 0;
  65.             this->stored = 0;
  66.         }
  67.         // デストラクタ
  68.         ~Hash() {
  69.             // Do Nothing
  70.         }
  71.         /* ******************************************
  72.          * ハッシュ表にデータを追加する
  73.          * ****************************************** */
  74.         void Add( data str ) {
  75.             int     h;          // ハッシュ値を格納
  76.             if( this->where( str.key ) == -1 ) {
  77.                 // ハッシュ値を計算しhに保存
  78.                 h = this->HashValue( str.key );
  79.                 // ハッシュ表の該当場所をチェックし、
  80.                 // 衝突していれば衝突回避するようにhを設定
  81.                 while( this->HashTable[h].flg == 1 ) {
  82.                     this->collision++;
  83.                     h++;
  84.                     if( h == TABLE_SIZE ) {
  85.                         h = 0;
  86.                     }
  87.                 }
  88.                 // データをハッシュ表に追加
  89.                 strcpy( this->HashTable[h].key, str.key );
  90.                 strcpy( this->HashTable[h].value, str.value );
  91.                 this->HashTable[h].flg = 1;
  92.                 this->stored = this->stored + 1;
  93.                 this->StoredPerAll = this->stored * 100 / TABLE_SIZE;
  94.             }
  95.         }
  96.         /* ******************************************
  97.          * データstrがこのハッシュで表現された集合に含まれるか
  98.          * @return  0なら含まれない、1なら含まれる
  99.          * ****************************************** */
  100.         int member( char *str ) {
  101.             if( this->where( str ) == -1 ) {
  102.                 return 0;
  103.             } else {
  104.                 return 1;
  105.             }
  106.         }
  107.         /* ******************************************
  108.          * データstrをこのハッシュで表現された集合から削除
  109.          * もし最初から存在しなければ、何もしないで終了
  110.          * ****************************************** */
  111.         void deletes( char *str ) {
  112.             if( this->member( str ) == 1 ) {
  113.                 // データを削除する
  114.                 this->HashTable[this->where(str)].key[0] = ’\0′;
  115.                 this->HashTable[this->where(str)].value[0] = ’\0′;
  116.                 this->HashTable[this->where(str)].flg = -1;
  117.                 this->stored = this->stored - 1;
  118.                 this->StoredPerAll = this->stored * 100 / TABLE_SIZE;
  119.             }
  120.         }
  121.  
  122.         /* ******************************************
  123.          * ハッシュからデータを取り出す
  124.          * ****************************************** */
  125.         data Get( char *keys ) {
  126.             int     idx;        // キーkeysの格納場所
  127.             data    ret;        // 戻り値として返すデータ
  128.             
  129.             idx = this->where( keys );
  130.             strcpy( ret.key, HashTable[idx].key );
  131.             strcpy( ret.value, HashTable[idx].value );
  132.             return ret;
  133.         }
  134.         /* ******************************************
  135.          * ハッシュの再構築
  136.          * ****************************************** */
  137.        void refresh() {
  138.             int     idx;
  139.             int     k = 0;
  140.             data    SwapTable[TABLE_SIZE];
  141.             // データを退避用変数に格納する。
  142.             for( idx=0; idx<TABLE_SIZE; idx++ ) {
  143.                 if( this->HashTable[idx].flg == 1 ) {
  144.                     strcpy( SwapTable[k].key, this->HashTable[idx].key );
  145.                     strcpy( SwapTable[k].value, this->HashTable[idx].value );
  146.                     SwapTable[k].flg = 1;
  147.                     k++;
  148.                 }
  149.             }
  150.             // テーブルをリセットする
  151.             for( idx=0; idx<TABLE_SIZE; idx++ ) {
  152.                 this->HashTable[idx].flg = 0;
  153.                 this->HashTable[idx].key[0] = ’\0′;
  154.                 this->HashTable[idx].value[0] = ’\0′;
  155.             }
  156.             this->collision = 0;
  157.             this->stored = 0;
  158.             this->StoredPerAll = 0;
  159.             // 退避したデータを格納する
  160.             for( idx=0; idx<k; idx++ ) {
  161.                 this->Add( SwapTable[idx] );
  162.             }
  163.         }
  164. };

関連記事

人気ブログランキングへ

[PR]

トラックバック

http://yamablo.com/2008/12/19-103002.php/trackback

One Response to “[C++]Hashクラス・改訂版,”

  1. yamablo » [C++] Hashクラス Says:

    [...] http://yamablo.com/2008/12/19-103002.phpの記事にHashクラスの改訂版があります。 [...]

コメント


Get Adobe Flash playerPlugin by wpburn.com wordpress themes