| Hash1.h |
|---|
// Hash1.h
#ifndef __HASH1_H__INCLUDED__
#define __HASH1_H__INCLUDED__
// ハッシュ表のサイズ(素数)
const unsigned HASH_SIZE = 11;
// ハッシュに登録しない値
const int HASH_UNUSED = -1;
// 二分探索木のノード
struct SNode
{
const char* key;
int value;
SNode* pNext[2];
};
// ハッシュ
struct SHash
{
SNode* pNode[HASH_SIZE];
};
void InitHash(SHash& hash); // 初期化
int HashFind(SHash& hash, const char* key); // データを検索
bool HashAdd(SHash& hash, const char* key, int value); // データを追加
void HashFree(SHash& hash); // 全削除
void HashDisp(SHash& hash); // データ全体を表示
#endif // #ifndef __HASH1_H__INCLUDED__ |
| Hash1.cpp |
// Hash1.cpp
#include <iostream.h>
#include <iomanip.h>
#include <string.h>
#include "Hash1.h"
////////////////////////////////////////////////////////////////////////////////
// static 関数のプロトタイプ宣言
// ハッシュ法のルーチン
// ハッシュ関数
static int HashFunc(const char* key);
// データを検索(ノードを返す)
static SNode*& HashFindNode(SHash& hash, const char* key);
// 二分探索木操作関数
// 初期化
static bool InitNode(SNode* pNode, const char* key, int value);
// ノードを探す
static SNode*& TreeFindNode(SNode*& pNode, const char* key);
// 全削除
static void TreeFree(SNode*& pNode);
// 二分探索木全体の表示
static int TreeDisp(SNode* pNode, int nDepth);
////////////////////////////////////////////////////////////////////////////////
// ハッシュ法のルーチン
// 初期化
void InitHash(SHash& hash)
{
for(int i = 0; i < HASH_SIZE; i++)
hash.pNode[i] = NULL;
}
// ハッシュ関数
// 先頭と最後と中央の文字コードの合計を HASH_SIZE で割った余りを返します
static int HashFunc(const char* key)
{
int nLen = strlen(key);
if(nLen == 0)
return 0;
nLen--;
return ((unsigned)key[0] + key[nLen / 2] + key[nLen]) % HASH_SIZE;
}
// データを検索(ノードを返す)
static SNode*& HashFindNode(SHash& hash, const char* key)
{
return TreeFindNode(hash.pNode[HashFunc(key)], key);
}
// データを検索
int HashFind(SHash& hash, const char* key)
{
SNode* pNode = HashFindNode(hash, key);
return pNode == NULL ? HASH_UNUSED : pNode->value;
}
// データを追加
bool HashAdd(SHash& hash, const char* key, int value)
{
SNode*& pNode = HashFindNode(hash, key);
if(pNode != NULL)
pNode->value = value;
else
{
pNode = new SNode;
if(pNode == NULL)
return false;
if(!InitNode(pNode, key, value))
{
delete pNode;
pNode = NULL;
return false;
}
}
return true;
}
// 全削除
void HashFree(SHash& hash)
{
for(int i = 0; i < HASH_SIZE; i++)
{
TreeFree(hash.pNode[i]);
hash.pNode[i] = NULL;
}
}
// データ全体を表示
void HashDisp(SHash& hash)
{
int nData = 0; // データの総数
for(int i = 0; i < HASH_SIZE; i++)
{
cout << "ハッシュ値 " << i << endl;
int nDataNode = TreeDisp(hash.pNode[i], 0);
cout << "データ数 " << nDataNode << endl;
nData += nDataNode;
char letter;
cin >> letter;
}
cout << "総データ数 " << nData << endl;
}
////////////////////////////////////////////////////////////////////////////////
// 二分探索木操作関数
// 初期化
static bool InitNode(SNode* pNode, const char* key, int value)
{
pNode->key = strdup(key);
if(key == NULL)
return false;
pNode->value = value;
pNode->pNext[0] = NULL;
pNode->pNext[1] = NULL;
return true;
}
// ノードを探す
static SNode*& TreeFindNode(SNode*& pNode, const char* key)
{
if(pNode == NULL)
return pNode;
int fComp = strcmp(pNode->key, key);
if(fComp == 0)
return pNode;
return TreeFindNode(pNode->pNext[fComp < 0], key);
}
// 全削除
static void TreeFree(SNode*& pNode)
{
if(pNode == NULL)
return;
TreeFree(pNode->pNext[0]);
TreeFree(pNode->pNext[1]);
delete pNode;
pNode = NULL;
}
// 二分探索木全体の表示
static int TreeDisp(SNode* pNode, int nDepth)
{
if(pNode == NULL)
return 0;
int nData = 1;
nData += TreeDisp(pNode->pNext[0], nDepth + 1);
cout << setw(nDepth * 2) << "" << pNode->key << " : " << pNode->value << endl;
nData += TreeDisp(pNode->pNext[1], nDepth + 1);
return nData;
} |
| Hash2.cpp |
// Hash2.cpp
#include <iostream.h>
#include <string.h>
#include "Hash1.h"
// 基本操作
static bool AddData(SHash& hash); // データの追加
static bool FindData(SHash& hash); // データの検索
int main()
{
SHash hash;
InitHash(hash);
while(AddData(hash));
while(FindData(hash));
HashDisp(hash);
return 0;
}
static bool AddData(SHash& hash)
{
char key[1024];
int value;
cout << "文字列と値を入力して下さい > " << flush;
cin >> key >> value;
if(strcmp(key, "q") == 0 || value == HASH_UNUSED)
return false;
return HashAdd(hash, key, value);
}
static bool FindData(SHash& hash)
{
char key[1024];
cout << "検索する文字列を入力して下さい > " << flush;
cin >> key;
if(strcmp(key, "q") == 0)
return false;
int value = HashFind(hash, key);
if(value == HASH_UNUSED)
cout << "見つかりません" << endl;
else
cout << "値は " << value << " です。" << endl;
return true;
} |
| 実行結果例 |
文字列と値を入力して下さい > Hash1.h 0
文字列と値を入力して下さい > #ifndef 1
文字列と値を入力して下さい > __HASH_H__INCLUDED__ 2
文字列と値を入力して下さい > #define 3
文字列と値を入力して下さい > const 4
文字列と値を入力して下さい > unsigned 5
文字列と値を入力して下さい > HASH_SIZE 6
文字列と値を入力して下さい > 11 7
文字列と値を入力して下さい > int 8
文字列と値を入力して下さい > HASH_UNUSED 9
文字列と値を入力して下さい > -1 10
文字列と値を入力して下さい > struct 11
文字列と値を入力して下さい > SNode 12
文字列と値を入力して下さい > char 13
文字列と値を入力して下さい > key 14
文字列と値を入力して下さい > value 15
文字列と値を入力して下さい > pNext[2] 16
文字列と値を入力して下さい > SHash 17
文字列と値を入力して下さい > pNode 18
文字列と値を入力して下さい > void 19
文字列と値を入力して下さい > InitHash 20
文字列と値を入力して下さい > hash 21
文字列と値を入力して下さい > HashFind 22
文字列と値を入力して下さい > bool 23
文字列と値を入力して下さい > HashAdd 24
文字列と値を入力して下さい > HashFree 25
文字列と値を入力して下さい > HashDisp 26
文字列と値を入力して下さい > #endif 27
文字列と値を入力して下さい > Hash1.cpp 28
文字列と値を入力して下さい > #include 29
文字列と値を入力して下さい > <iostream.h> 30
文字列と値を入力して下さい > <iomanip.h> 31
文字列と値を入力して下さい > <string.h> 32
文字列と値を入力して下さい > "Hash1.h" 33
文字列と値を入力して下さい > static 34
文字列と値を入力して下さい > HashFindNode 35
文字列と値を入力して下さい > InitNode 36
文字列と値を入力して下さい > TreeFindNode 37
文字列と値を入力して下さい > TreeFree 38
文字列と値を入力して下さい > TreeDisp 39
文字列と値を入力して下さい > nDepth 40
文字列と値を入力して下さい > for 41
文字列と値を入力して下さい > i 42
文字列と値を入力して下さい > hash.pNode[i] 43
文字列と値を入力して下さい > NULL 44
文字列と値を入力して下さい > nLen 45
文字列と値を入力して下さい > strlen 46
文字列と値を入力して下さい > return 47
文字列と値を入力して下さい > -- 48
文字列と値を入力して下さい > / 49
文字列と値を入力して下さい > ?: 50
文字列と値を入力して下さい > pNode->value 51
文字列と値を入力して下さい > != 52
文字列と値を入力して下さい > false 53
文字列と値を入力して下さい > delete 54
文字列と値を入力して下さい > true 55
文字列と値を入力して下さい > cout 56
文字列と値を入力して下さい > << 57
文字列と値を入力して下さい > endl 58
文字列と値を入力して下さい > nDataNode 59
文字列と値を入力して下さい > nData 60
文字列と値を入力して下さい > letter 61
文字列と値を入力して下さい > cin 62
文字列と値を入力して下さい > >> 63
文字列と値を入力して下さい > strdup 64
文字列と値を入力して下さい > if 65
文字列と値を入力して下さい > fComp 66
文字列と値を入力して下さい > strcmp 67
文字列と値を入力して下さい > new 68
文字列と値を入力して下さい > setw 69
文字列と値を入力して下さい > Hash2.cpp 70
文字列と値を入力して下さい > AddData 71
文字列と値を入力して下さい > FindData 72
文字列と値を入力して下さい > main 73
文字列と値を入力して下さい > 1024 74
文字列と値を入力して下さい > "q" 75
文字列と値を入力して下さい > ハッシュ法のテストプログラム 76
文字列と値を入力して下さい > ハッシュ表のサイズ(素数) 77
文字列と値を入力して下さい > ハッシュに登録しない値 78
文字列と値を入力して下さい > 二分探索木のノード 79
文字列と値を入力して下さい > ハッシュ 80
文字列と値を入力して下さい > 初期化 81
文字列と値を入力して下さい > データを検索 82
文字列と値を入力して下さい > データを追加 83
文字列と値を入力して下さい > 全削除 84
文字列と値を入力して下さい > データ全体を表示 85
文字列と値を入力して下さい > 関数のプロトタイプ宣言 86
文字列と値を入力して下さい > ハッシュ法のルーチン 87
文字列と値を入力して下さい > ハッシュ関数 88
文字列と値を入力して下さい > データを検索(ノードを返す) 89
文字列と値を入力して下さい > 二分探索木操作関数 90
文字列と値を入力して下さい > ノードを探す 91
文字列と値を入力して下さい > 二分探索木全体の表示 92
文字列と値を入力して下さい > 先頭と最後と中央の文字コードの合計 93
文字列と値を入力して下さい > 割った余りを返します 94
文字列と値を入力して下さい > データの総数 95
文字列と値を入力して下さい > 基本操作 96
文字列と値を入力して下さい > データの追加 97
文字列と値を入力して下さい > データの検索 98
文字列と値を入力して下さい > 最後の追加要素 99
文字列と値を入力して下さい > q -1
検索する文字列を入力して下さい > value
値は 15 です。
検索する文字列を入力して下さい > int
値は 8 です。
検索する文字列を入力して下さい > ハッシュ関数
値は 88 です。
検索する文字列を入力して下さい > letter
値は 61 です。
検索する文字列を入力して下さい > cin
値は 62 です。
検索する文字列を入力して下さい > >>
値は 63 です。
検索する文字列を入力して下さい > SHash
値は 17 です。
検索する文字列を入力して下さい > FindData
値は 72 です。
検索する文字列を入力して下さい > #include
値は 29 です。
検索する文字列を入力して下さい > "q"
値は 75 です。
検索する文字列を入力して下さい > double
見つかりません
検索する文字列を入力して下さい > ハッシュ
値は 80 です。
検索する文字列を入力して下さい > 全削除
値は 84 です。
検索する文字列を入力して下さい > delete
値は 54 です。
検索する文字列を入力して下さい > while
見つかりません
検索する文字列を入力して下さい > new
値は 68 です。
検索する文字列を入力して下さい > Hash1.h
値は 0 です。
検索する文字列を入力して下さい > <iostream.h>
値は 30 です。
検索する文字列を入力して下さい > q
ハッシュ値 0
TreeDisp : 39
TreeFree : 38
endl : 58
hash.pNode[i] : 43
nDataNode : 59
new : 68
strcmp : 67
strdup : 64
ハッシュ関数 : 88
基本操作 : 96
二分探索木操作関数 : 90
データ数 11
n
ハッシュ値 1
<iomanip.h> : 31
HashAdd : 24
HashFind : 22
delete : 54
int : 8
true : 55
初期化 : 81
データ数 7
n
ハッシュ値 2
Hash1.cpp : 28
HashDisp : 26
HashFree : 25
最後の追加要素 : 99
データ数 4
n
ハッシュ値 3
-- : 48
FindData : 72
Hash2.cpp : 70
HashFindNode : 35
false : 53
static : 34
unsigned : 5
ハッシュ表のサイズ(素数) : 77
関数のプロトタイプ宣言 : 86
二分探索木のノード : 79
データ数 10
n
ハッシュ値 4
#include : 29
11 : 7
<< : 57
InitNode : 36
TreeFindNode : 37
if : 65
struct : 11
データ全体を表示 : 85
データ数 8
n
ハッシュ値 5
"q" : 75
#endif : 27
#ifndef : 1
<iostream.h> : 30
HASH_SIZE : 6
HASH_UNUSED : 9
Hash1.h : 0
pNode : 18
pNode->value : 51
setw : 69
先頭と最後と中央の文字コードの合計 : 93
データ数 11
n
ハッシュ値 6
!= : 52
1024 : 74
cin : 62
const : 4
fComp : 66
pNext[2] : 16
データの検索 : 98
データを検索 : 82
ハッシュ法のテストプログラム : 76
データ数 9
n
ハッシュ値 7
"Hash1.h" : 33
#define : 3
-1 : 10
<string.h> : 32
InitHash : 20
cout : 56
i : 42
nData : 60
nDepth : 40
二分探索木全体の表示 : 92
データ数 10
n
ハッシュ値 8
?: : 50
NULL : 44
for : 41
hash : 21
letter : 61
main : 73
value : 15
データの総数 : 95
ハッシュ : 80
全削除 : 84
データ数 10
n
ハッシュ値 9
/ : 49
SHash : 17
SNode : 12
bool : 23
char : 13
strlen : 46
データの追加 : 97
データを検索(ノードを返す) : 89
データを追加 : 83
ノードを探す : 91
割った余りを返します : 94
データ数 11
n
ハッシュ値 10
>> : 63
AddData : 71
__HASH_H__INCLUDED__ : 2
key : 14
nLen : 45
return : 47
void : 19
ハッシュに登録しない値 : 78
ハッシュ法のルーチン : 87
データ数 9
n
総データ数 100 |
Last update was done on 2001.2.13
この講座の著作権はロベールが保有しています