我有一个使用STL的开放哈希表。
typedef std::list<int> LIST;
typedef std::vector<LIST> HASH_TABLE;
我通过填充空列表来初始化哈希表。
LIST mt_list;
HASH_TABLE hTable;
hTable.assign(7, mt_list);
现在,如果我想根据以下内容向表中添加一个int:
hKey = (value*value) % 7;
我用
hTable[hKey].push_back(value);
它应该正常吗?我无法让它发挥作用。
void addValue(int value){
if(val_find(value)){
std::cout << "WARNING: duplicate input: " << value << std::endl;
}
else{
calc_hash_bucket(value); //set hKey
hTable[hKey].push_back(value); //push value into list
}
}
上面的代码不会将元素添加到向量中的任何列表。
另外,当我想使用迭代器遍历向量和向量中的列表时,如何从列表中一次获取一个元素,这样我就可以找到一个特定的值,该值可能已经存在,也可能不存在清单?
这就是我在哈希表中查找值的原因:
bool val_find(int value){
if(mt_hash()){
return false;
}
else{
for(HASH_ITER h_iter = hTable.begin(); h_iter != hTable.end(); ++h_iter){
for(LIST_ITER l_iter = h_iter->begin(); l_iter != h_iter->end(); ++l_iter){
if(*l_iter == value){
return true;
}
}
}
}
return false;
}
我很难过。我不明白为什么它不会将值添加到任何列表中。
我觉得我应该提到这是一个头文件和我创建的类的一部分。 (我不知道这是否重要)
编辑:警告语句不会打印。要回答问题,mt_hash()函数会检查哈希表是否为空,并且我已多次检查它以确保它正确输出。我修正了hTable_1与hTable的区别,它们是相同的。我把它放到问题中时,我只是忘了改变它。
bool mt_hash(void){ //is hash table empty?
for(unsigned int i = 0; i < hTable.size(); ++i){
if(!hTable.at(i).empty()){ //if not empty return false
return false;
}
}
return true; //else return true
}
谢谢, 扎克
答案 0 :(得分:1)
正如普拉丹指出的那样,有一点点缺失。 mt_hash()
的实施是什么? hTable_1
和hTable
是同一个对象吗?
下面,我已经使用了上面的代码,并将它们放在一个包含隐含功能的结构中。请注意三项更改:hTable
替换hTable_1
中的val_find()
; addValue()
使用局部变量来存储哈希键;并且通过保持简单的元素计数来实现mt_hash()
。
#include <list>
#include <vector>
#include <iostream>
#include <iomanip>
struct open_hash {
typedef std::list<int> LIST;
typedef std::vector<LIST> HASH_TABLE;
typedef LIST::const_iterator LIST_ITER;
typedef HASH_TABLE::const_iterator HASH_ITER;
HASH_TABLE hTable;
int nbins;
int elem_count;
explicit open_hash(int nbins_): nbins(nbins_), elem_count(0) {
init_hash();
}
void init_hash() {
LIST mt_list;
hTable.assign(nbins, mt_list);
}
int hash_bucket(int value) const {
return (value*value)%nbins;
}
bool mt_hash() const {
return elem_count==0;
}
bool val_find(int value) const {
if (mt_hash()) {
return false;
}
for (HASH_ITER h_iter = hTable.begin(); h_iter != hTable.end(); ++h_iter){
for (LIST_ITER l_iter = h_iter->begin(); l_iter != h_iter->end(); ++l_iter){
if (*l_iter == value) {
return true;
}
}
}
return false;
}
void addValue(int value) {
if (val_find(value)) {
std::cout << "WARNING: duplicate input: " << value << std::endl;
}
else {
int hKey=hash_bucket(value);
hTable[hKey].push_back(value); //push value into list
++elem_count;
}
}
};
int main() {
open_hash H(7);
std::vector<int> vals={3,1,9,2,10,4,3};
for (int v: vals) {
H.addValue(v);
}
for (int i=1; i<=10; ++i) {
std::cout << "val_find(" << i << "):\t" << std::boolalpha << H.val_find(i) << "\n";
}
}
这会产生预期的输出:
WARNING: duplicate input: 3
val_find(1): true
val_find(2): true
val_find(3): true
val_find(4): true
val_find(5): false
val_find(6): false
val_find(7): false
val_find(8): false
val_find(9): true
val_find(10): true
我怀疑最初的问题在于addValue()
和val_find()
引用了不同的哈希对象,或者mt_hash()
中的一个问题误报了该表是空的,而事实上并非如此。 / p>
答案 1 :(得分:0)
这个问题的答案是在主cpp文件中创建类型为HASH_TABLE的类对象,然后通过引用将它传递给调用所有命令和i / o的函数(getCmd)。
我在main()中调用了“getCmd”函数,该函数(每次调用它)都会创建一个HASH_TABLE类的NEW实例,用一个新的空对象有效地“替换”前一个对象。 (虽然我怀疑它实际上并没有取代之前的对象。我认为前一个对象仍在占用内存,但它没有被使用)
我没有发布问题区域的代码,因为我不知道问题出在哪里。
感谢您的帮助!