使用rehash的C++哈希表问题
C++ Hashtable issues with rehash
至于我的学校作业,当它达到%70-90负载时,我必须更新我的哈希表大小。我在重新哈希表方面遇到了问题。我无法修改tableSize(因为我用const-static创建了它。我不得不修改,因为它不允许我这样做(。我也不能修改哈希表,因为它是不可修改的值。我认为我的构造器是错的,但我不能自己弄清楚。
感谢您的帮助。
hash_table.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include "hash_table.h"
using namespace std;
hash_table::hash_table()
{
for (int i = 0; i < tableSize; i++) {
HashTable[i] = new item;
HashTable[i]->name = "";
HashTable[i]->info.documentName = "";
HashTable[i]->info.count = 1;
HashTable[i]->info.next = NULL;
HashTable[i]->next = NULL;
}
}
int hash_table::Hash(string key)
{
int hash = 0;
int index;
for (int i = 0; i < key.length(); i++) {
hash = (hash + (int)key[i]) * 17;
}
index = hash % tableSize;
return index;
}
void hash_table::AddItem(string name,string document)
{
int index = Hash(name);
int check = size / tableSize;
if(check > 0.78){
reHash();
}
if (HashTable[index]->name == "") {
HashTable[index]->name = name;
HashTable[index]->info.documentName = document;
HashTable[index]->info.count = 1;
size++;
}
else if (HashTable[index]->name == name) {
if (HashTable[index]->info.documentName == document) {
HashTable[index]->info.count++;
}
else if (HashTable[index]->info.next != NULL) {
Document* checkPtr = &HashTable[index]->info;
while (HashTable[index]->info.next != NULL) {
checkPtr = checkPtr->next;
if (checkPtr != NULL) {
if (checkPtr->documentName == document) {
checkPtr->count++;
}
}
else {
break;
}
}
}
else {
Document* tempPtr = &HashTable[index]->info;
Document* t = new Document;
t->documentName = document;
t->count = 1;
t->next = NULL;
while (tempPtr->next != NULL) {
tempPtr = tempPtr->next;
}
tempPtr->next = t;
}
}
else {
item* Ptr = HashTable[index];
item* n = new item;
n->name = name;
n->next = NULL;
while (Ptr->next != NULL) {
Ptr = Ptr->next;
}
Ptr->next = n;
}
}
int hash_table::NumberOfItemsInIndex(int index)
{
int count = 0;
if (HashTable[index]->name == "") {
return count;
}
else {
count++;
item* Ptr = HashTable[index];
while (Ptr->next != NULL) {
count++;
Ptr = Ptr->next;
}
}
return count;
}
void hash_table::PrintTable() // CAN USE AS CALCULATING TOTAL NUMBER
{
int number;
for (int i = 0; i < tableSize; i++) {
number = NumberOfItemsInIndex(i);
cout << "----------------" << endl;
cout << "index = " << i << endl;
cout << HashTable[i]->name << endl;
cout << HashTable[i]->info.count << endl;
cout << "# of items = " << number << endl;
cout << "----------------" << endl;
}
}
void hash_table::PrintItemsInIndex(int index)
{
item* Ptr = HashTable[index];
if (Ptr->name == "empty") {
cout << "index = " << index << " is empty" << endl;
}
else {
cout << "index " << index << "countains the following item" << endl;
while (Ptr != NULL) {
cout << "--------------" << endl;
cout << Ptr->name << endl;
cout << Ptr->info.count << endl;
cout << "--------------" << endl;
Ptr = Ptr->next;
}
}
}
void hash_table::FindString(string name)
{
int index = Hash(name);
bool foundQuery = false;
item *Ptr = HashTable[index];
Document* checkPtr = NULL;
while (Ptr != NULL) {
if (Ptr->name == name) {
foundQuery = true;
checkPtr = &Ptr->info;
}
Ptr = Ptr->next;
}
if (foundQuery == true) {
while (checkPtr != NULL) {
cout << "in document " << checkPtr->documentName << ", " << name << " found " << checkPtr->count << " times." << endl;
checkPtr = checkPtr->next;
}
}
else {
cout << "No document contains the given query" << endl;
}
}
void hash_table::reHash()
{
int oldCapacity = tableSize;
tableSize = tableSize * 2 + 1;
item** newHashTable = new item*[tableSize];
for (int i = 0; i < oldCapacity; i++) {
item *n = HashTable[i];
while (n != NULL) {
item *tmp = n;
n = n->next;
item*& bucket = newHashTable[hash_table::Hash(tmp->name) % tableSize];
tmp->next = bucket;
bucket = tmp;
}
}
delete[] HashTable;
HashTable = newHashTable;
}
hash_table.h
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
#ifndef HASH_H
#define HASH_H
struct Document {
string documentName;
int count;
Document* next;
};
struct item {
string name;
item* next;
struct Document info;
};
class hash_table{
private:
const static int tableSize = 26;
item* HashTable[tableSize];
public:
hash_table();
int Hash(string key);
void AddItem(string name, string document);
int NumberOfItemsInIndex(int index);
void PrintTable();
void PrintItemsInIndex(int index);
void FindString(string name);
void reHash();
int size = 0;
};
#endif // !HASH_H
通常,要使数组变大,需要制作一个更大的数组,并将旧数组的内容复制到新数组。你想通了!
通过将table_size设为常量,然后在此处声明一个固定大小的数组,可以将您锁定为固定的数组大小。
const static int tableSize = 26;
item* HashTable[tableSize];
如果您将tableSize设置为上面的一个变量,并使初始数组更像这个
item** newHashTable = new item*[tableSize];
那么你成功的机会就大了!既然这是一个学校练习,为你做代码是不对的。。。
不过,一般来说,在程序执行期间需要更改数组大小的情况下,使用向量要好得多。这些可以在执行过程中随意扩展,非常值得阅读和做一些例子。
相关文章:
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- C++中的并发哈希表
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 与C++哈希表的基础知识混淆
- 调整大小和复制哈希表数组中的元素
- 带链接的基本哈希表
- C++哈希表中,两个相同的实现,但一个给出错误
- 如果索引不是整数,我们如何在 C++ 中插入哈希表
- 查找项目在哈希表中的位置
- 为什么C++ STL 哈希表 (unordered_map) 不接受向量作为键
- 使用rehash的C++哈希表问题
- 生活游戏哈希表 .h 文件模板问题
- 使用输入数较少的哈希表有什么问题
- 在简单的哈希表中解决内存泄漏和语法问题
- C++关于哈希表的问题
- 一些哈希表/unordered_map问题
- 哈希表添加和打印功能问题
- C关于哈希表的问题