使用迭代器打开散列,添加元素和查找元素

时间:2015-02-14 06:24:42

标签: c++ hash

我有一个使用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
}

谢谢, 扎克

2 个答案:

答案 0 :(得分:1)

正如普拉丹指出的那样,有一点点缺失。 mt_hash()的实施是什么? hTable_1hTable是同一个对象吗?

下面,我已经使用了上面的代码,并将它们放在一个包含隐含功能的结构中。请注意三项更改: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实例,用一个新的空对象有效地“替换”前一个对象。 (虽然我怀疑它实际上并没有取代之前的对象。我认为前一个对象仍在占用内存,但它没有被使用)

我没有发布问题区域的代码,因为我不知道问题出在哪里。

感谢您的帮助!