C++ 将静态哈希表转换为动态哈希表
我将被分配将给定的哈希表从静态内存分配更改为动态内存分配,以便在程序运行时可以分配超过限制的更多内存。我并不是在要求解决这个问题,我只是问是否有人知道一个好的起点,或者我需要注意代码的哪些方面,因为我对哈希表有点迷茫和困惑。我知道枚举和构造函数需要更改,但我不确定还有多少其他内容。以下是给出的代码,并提前感谢您的建议:C++ 将静态哈希表转换为动态哈希表,c++,hashtable,C++,Hashtable,我将被分配将给定的哈希表从静态内存分配更改为动态内存分配,以便在程序运行时可以分配超过限制的更多内存。我并不是在要求解决这个问题,我只是问是否有人知道一个好的起点,或者我需要注意代码的哪些方面,因为我对哈希表有点迷茫和困惑。我知道枚举和构造函数需要更改,但我不确定还有多少其他内容。以下是给出的代码,并提前感谢您的建议: #ifndef TABLE1_H #define TABLE1_H #include <cstdlib> // Provides size_t #include
#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib> // Provides size_t
#include <cassert> // Provides assert
namespace main_savitch_12A
{
template <class RecordType>
class table
{
public:
enum { CAPACITY = 30 };
// CONSTRUCTOR
table( );
// MODIFICATION MEMBER FUNCTIONS
void insert(const RecordType& entry);
void remove(int key);
// CONSTANT MEMBER FUNCTIONS
bool is_present(int key) const;
void find(int key, bool& found, RecordType& result) const;
size_t size( ) const { return used; }
private:
// MEMBER CONSTANTS -- These are used in the key field of special records.
enum { NEVER_USED = -1 };
enum { PREVIOUSLY_USED = -2 };
// MEMBER VARIABLES
RecordType data[CAPACITY];
size_t used;
// HELPER FUNCTIONS
size_t hash(int key) const;
size_t next_index(size_t index) const;
void find_index(int key, bool& found, size_t& index) const;
bool never_used(size_t index) const;
bool is_vacant(size_t index) const;
};
template <class RecordType>
table<RecordType>::table( )
{
size_t i;
used = 0;
for (i = 0; i < CAPACITY; ++i)
data[i].key = NEVER_USED; // Indicates a spot that's never been used.
}
template <class RecordType>
void table<RecordType>::insert(const RecordType& entry)
// Library facilities used: cassert
{
bool already_present; // True if entry.key is already in the table
size_t index; // data[index] is location for the new entry
assert(entry.key >= 0);
// Set index so that data[index] is the spot to place the new entry.
find_index(entry.key, already_present, index);
// If the key wasn't already there, then find the location for the new entry.
if (!already_present)
{
assert(size( ) < CAPACITY);
index = hash(entry.key);
while (!is_vacant(index))
index = next_index(index);
++used;
}
data[index] = entry;
size_t i;
for (i=0; i<CAPACITY; i++) cout << data[i].key << ' ';
cout << endl;
}
template <class RecordType>
void table<RecordType>::remove(int key)
// Library facilities used: cassert
{
bool found; // True if key occurs somewhere in the table
size_t index; // Spot where data[index].key == key
assert(key >= 0);
find_index(key, found, index);
if (found)
{ // The key was found, so remove this record and reduce used by 1.
data[index].key = PREVIOUSLY_USED; // Indicates a spot that's no longer in use.
--used;
}
}
template <class RecordType>
bool table<RecordType>::is_present(int key) const
// Library facilities used: assert.h
{
bool found;
size_t index;
assert(key >= 0);
find_index(key, found, index);
return found;
}
template <class RecordType>
void table<RecordType>::find(int key, bool& found, RecordType& result) const
// Library facilities used: cassert.h
{
size_t index;
assert(key >= 0);
find_index(key, found, index);
if (found)
result = data[index];
}
template <class RecordType>
inline size_t table<RecordType>::hash(int key) const
{
return (key % CAPACITY);
}
template <class RecordType>
inline size_t table<RecordType>::next_index(size_t index) const
// Library facilities used: cstdlib
{
return ((index+1) % CAPACITY);
}
template <class RecordType>
void table<RecordType>::find_index(int key, bool& found, size_t& i) const
// Library facilities used: cstdlib
{
size_t count; // Number of entries that have been examined
count = 0;
i = hash(key);
while((count < CAPACITY) && (data[i].key != NEVER_USED) && (data[i].key != key))
{
++count;
i = next_index(i);
}
found = (data[i].key == key);
}
template <class RecordType>
inline bool table<RecordType>::never_used(size_t index) const
{
return (data[index].key == NEVER_USED);
}
template <class RecordType>
inline bool table<RecordType>::is_vacant(size_t index) const
{
return (data[index].key == NEVER_USED);// || (data[index].key == PREVIOUSLY_USED);
}
}
#endif
#如果NDEF表1\u H
#定义表1_H
#包含//提供大小\u t
#include//提供断言
名称空间main_savitch_12A
{
模板
类表
{
公众:
枚举{容量=30};
//建造师
表();
//修改成员函数
无效插入(常量记录类型和条目);
无效删除(int键);
//常数成员函数
布尔值为当前值(整数键)常量;
无效查找(int键、bool和found、记录类型和结果)常量;
size\u t size()常量{return used;}
私人:
//成员常量——这些常量用于特殊记录的键字段。
枚举{NEVER_USED=-1};
枚举{以前使用的=-2};
//成员变量
记录类型数据[容量];
使用的尺寸;
//辅助函数
大小\u t散列(整数键)常量;
大小下一个索引(大小索引)常量;
无效查找索引(整型键、布尔和查找、大小和索引)常量;
布尔从未使用过(大小索引)常数;
bool为空(大小索引)常数;
};
模板
表::表()
{
尺寸i;
使用=0;
对于(i=0;i=0);
//设置索引,使data[index]成为放置新条目的位置。
查找索引(entry.key,已存在,索引);
//如果钥匙不在那里,则找到新条目的位置。
如果(!已存在)
{
断言(大小()<容量);
索引=散列(entry.key);
而(!是空的(索引))
索引=下一个索引(索引);
++使用;
}
数据[索引]=条目;
尺寸i;
对于(i=0;i需要考虑的几点:
- 您可以使用
vector
代替C样式数组来保存元素,因为它允许动态调整大小
- 当您需要扩展表时,您必须重新刷新所有现有元素,以将它们放在新容器中的新位置(重新刷新完成后,您可以将其与现有容器交换)
- 您将希望能够指定决定何时增长的负载系数
- 您需要决定是否允许容器收缩分配的空间,同样是在某个阈值下
@Mark B创意就是答案
想要添加:
建议您的表大小
容量
为素数。用素数修改弱哈希函数哈希(键)
有助于分散。(好的哈希函数不需要任何帮助。)
你的生长步数通常是指数级的,可以建立在一个查找表中。不同的作者建议比率在1.5和4之间。例如,Grow2x[]={0,1,3,7,13,31,61,…(素数的幂次仅为2}
假设每次增长2倍,且增长负荷为100%。那么收缩负荷应为70%(几何平均值为100%/2倍和100%)。如果插入/删除徘徊在临界水平,则应避免增长/收缩