ハッシュ関数 のキー値を走査するには? – プログラミング – Home

ハッシュ関数 のキー値を走査するには?
 
通知
すべてクリア

[解決済] ハッシュ関数 のキー値を走査するには?


キー坊
 キー坊
(@キー坊)
ゲスト
結合: 14年前
投稿: 5
Topic starter  

std::map を用いてハッシュ関数を実装する、事例が「ロベールのC++入門」という本に掲
載されています
setting[0101] = 元旦;
掲載されている事例では、Hash クラスのVALUE& operator[](const KEY& key)をオーバー
ライドさせ、
std::string 型のデータがstd::map に挿入される仕組みになっており
std::cout setting[0101] << std::endl;
このようにすればキー値に紐付けられた値が取り出せれます。
このプログラムを、後で日付データが利用したいため、下記のようにvector コンテナを
用いて実装しました。
typedef Hash<string, string> Setting;
vector<string> v;
Setting setting;
v.push_back(0101);
setting[v[0]] = 元旦;

ここからが質問なのですが、
vector コンテナを用いずにmap のイテレータを利用して日付データ(キー値)を走査し
たり扱いたいのですが、イテレータを付加しbegin() end() が使えるようにするには、ど
の様にしたら良いでしょうか。

# HashFn.h
#ifndef HASHFN_H_
#define HASHFN_H_

#include <string>
#include <cstddef>

// デフォルトのハッシュ関数
template <typename TYPE>
class HashFn
{
public:
static size_t Get(const TYPE& value);
static const size_t SIZE = 23; // ハッシュ表のサイズ
};

template<>
size_t HashFn<std::string>::Get(const std::string &value)
{
size_t size = value.size();
const unsigned char* p =
reinterpret_cast<const unsigned char*>(value.data());
return (p[0] + p[size / 2] + p[size - 1]) % SIZE;
}
#endif // #ifndef HASHFN_H_

# Hash.h
#ifndef HASH_H_
#define HASH_H_

#include HashFn.h
#include <map>
#include <stdexcept>

template <
typename KEY, // キーの型
typename VALUE, // 扱う値の型
typename HASH_FN = HashFn<KEY> // ハッシュ関数
>

class Hash
{
private:
typedef std::map<KEY, VALUE> Map;
typedef typename Map::const_iterator CIterator;

public:
VALUE& operator[](const KEY& key) {
size_t hashValue = HASH_FN::Get(key);
return m_hashTable[hashValue][key];
}

const VALUE& operator[](const KEY& key) const {
size_t hashValue = HASH_FN::Get(key);
const Map& map = m_hashTable[hashValue];
CIterator it = map.find(key);
if(it == map.end()) {
throw std::out_of_range(見つかりませんでした);
}
return it->second;
}
private:
Map m_hashTable[HASH_FN::SIZE];
};
#endif // #ifndef HASH_H_

# Hash1.cpp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include Hash.h

using namespace std;

typedef Hash<string, string> Setting;
vector<string> v;
int main()
{
Setting setting;
v.push_back(0101);
v.push_back(0211);
v.push_back(0429);
v.push_back(0503);
v.push_back(0504);
v.push_back(0505);
v.push_back(1103);
v.push_back(1123);
v.push_back(1223);

// 固定祭日処理
setting[v[0]] = 元旦;
setting[v[1]] = 建国記念の日;
setting[v[2]] = 昭和の日;
setting[v[3]] = 憲法記念日;
setting[v[4]] = みどりの日;
setting[v[5]] = 子供の日;
setting[v[6]] = 文化の日;
setting[v[7]] = 勤労感謝の日;
setting[v[8]] = 天皇誕生日;

vector<string>::iterator it;
for(it = v.begin(); it < v.end(); it++)
cout << setting[*it] << endl;
return 0;
}


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 15年前
投稿: 64
 

確認ですが、きょうびの標準C++ライブラリには
ハッシュ表:unordered_set/multiset/map/multimapが提供されてるのは
百も承知での質問でしょうか?

// VC++10 で動作確認
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>

using namespace std;

int main() {
unordered_map<string,string> setting;
setting[0101] = 元旦;
setting[0211] = 建国記念の日;
setting[0429] = 昭和の日;
setting[0503] = 憲法記念日;
setting[0504] = みどりの日;
setting[0505] = 子供の日;
setting[1103] = 文化の日;
setting[1123] = 勤労感謝の日;
setting[1223] = 天皇誕生日;

for_each(setting.begin(), setting.end(),
[](const unordered_map<string,string>::value_type& item)
{ cout << item.first << ':' << item.second << endl; });
}


返信引用
キー坊
 キー坊
(@キー坊)
ゲスト
結合: 14年前
投稿: 5
Topic starter  

επιστημη さんお世話になります。
>>ハッシュ表:unordered_set/multiset/map/multimap ?
C++0x というやつですね、知りませんでした・・・というか、あなたの出筆された、
「C++テンプレートテクニック」のp324 に書いてありますね、よく読んでいませんでした。
環境を書き忘れていましたが、VC8 なので、この関数は使えないので
VC10 をインストルして、試したところ動作が確認できました、後でg++ でも試してみた
いと思います。
VC8 だと面倒なコードになるんでしょうね、「C++テンプレートテクニック」のSFINAE の
ところを真似て、begin()、end() を実装しようとしたのですが、理解力といいますか、
応用力が無くて頓挫しました。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 15年前
投稿: 64
 

VC8でならBoost使ってはいかがでしょうか。

http://www.boost.org/doc/libs/1_43_0/doc/html/boost_tr1/subject_list.html#boost
_tr1.subject_list.unordered_map


返信引用
キー坊
 キー坊
(@キー坊)
ゲスト
結合: 14年前
投稿: 5
Topic starter  

επιστημη さん
ありがとうございました。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 15年前
投稿: 64
 

VC++9なら(標準じゃないけど)hash_set/hash_mapなんてのも入ってますな。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました