繁体   English   中英

为什么我在 c++ 中使用链接程序的散列给出了意外的 output?

[英]Why my hashing using chaining program in c++ gives unexpected output?

我正在尝试从头开始在 C++ 中实现散列。 除了 output 之外,一切似乎都很好。 我正在使用链接实现散列。 这种散列风格使用链表来处理冲突。 我使用了我在 HashTable class 中定义的 HashNode 类型的链表数组。

#include <bits/stdc++.h>
using namespace  std;

template<class K,class V>
class HashTable{
    class HashNode{
        friend class HashTable;
    public:
        K key;
        V val;
        HashNode(K key, V val){
            this->key = key;
            this->val = val;
        }
        K getKey(){
            return this->key;
        }
        V getVal(){
            return this->val;
        }
    };

    int cap;
    list<HashNode>* ptr = new list<HashNode>[cap];
public:
    //constructor
    HashTable(int x){
        cap = x;    
    }

    //hash function
    hash<K> hashIt;
    int getHash(K k){
        return hashIt(k)%cap;
    }

    //adding pair
    void addPair(K k, V v){
        int index = getHash(k);
        bool found = false;
        auto bucket = *(ptr + index);
        for(auto x = bucket.begin();x!=bucket.end();x++){
            if((*x).key == k){
                (*x).val = v;
                found = true;
                break;
            }
        }
        if(!found){
            bucket.push_back(HashNode(k,v));
        }
    }

    //display function
    void display(){
        for(int i=0;i<cap;i++){
            cout<<"\n Bucket " + i<<" =>"<<endl;
            auto bucket  = *(ptr + i);
            for(auto x = bucket.begin();x!=bucket.end();x++ ){
                cout<<(*x).getKey()<<" : "<<(*x).getVal()<<endl;
            }
        }
    }
};
int main(){
    HashTable<string,int> H(13);
    H.addPair("IND",20);
    H.addPair("PAK",10);
    H.display();
}

但是,当我运行程序时,我得到以下 output

 Bucket  =>
 Bucket  =>
Bucket  =>
ucket  =>
cket  =>
ket  =>
et  =>
t  =>
  =>
 =>
 => =>
=> =>
> =>

如果有人能指出错误,那将很有帮助。

一个错误是

cout<<"\n Bucket " + i<<" =>"<<endl;

应该

cout << "\n Bucket " << i << " =>" << endl;

另一个错误在这里

    auto bucket = *(ptr + index);
    for(auto x = bucket.begin();x!=bucket.end();x++){
        if((*x).key == k){
            (*x).val = v;
            found = true;
            break;
        }
    }
    if(!found){
        bucket.push_back(HashNode(k,v));
    }

此代码复制存储桶,然后将节点插入到存储桶副本中,而不是在数组中的原始存储桶中。 这就是为什么您的 hash 表即使在您插入项目后仍为空的原因。

这是重写的代码以避免这种情况

    auto bucket = ptr + index;
    for (auto x = bucket->begin(); x!=bucket->end(); ++x) {
        if (x->key == k) {
            x->val = v;
            found = true;
            break;
        }
    }
    if (!found) {
        bucket->push_back(HashNode(k, v));
    }

在此代码中, bucket是一个指针,因此没有创建 bucket 的副本(您可以使用引用实现相同的效果)。

您在打印程序中遇到了同样的问题,您在打印之前复制了存储桶。 这不会停止它的工作,但它效率低下,您应该以与上述相同的方式修复它。

请不要将 Java 直接转换为 C++。 C++ 是一种非常不同的语言。 看这个:

#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>

template<class K, class V>
class HashTable {
    struct HashNode {
        K key;
        V val;
    };

    std::vector<std::vector<HashNode>> buckets;

    //hash function
    int getBucketIdx(K const& k) const {
        return std::hash<K>{}(k) % buckets.size();
    }
public:
    //constructor
    HashTable(int cap) : buckets(cap) {}

    //adding pair
    void addPair(K const& k, V const& v) {
        auto& bucket = buckets[getBucketIdx(k)];
        auto const loc = std::find_if(begin(bucket), end(bucket),
            [&](HashNode const& hn) { return hn.key == k; });
        if (loc != end(bucket)) {
            loc->val = v;
        } else {
            bucket.emplace_back(HashNode{k, v});
        }
    }

    //display function
    void display() const {
        for(int i = 0; i < buckets.size(); ++i){
            std::cout << "Bucket " << i << " =>\n";
            for(auto const& hn : buckets[i]){
                std::cout << hn.key
                 << " : " << hn.val << '\n';
            }
        }
    }
};
int main() {
    HashTable<std::string, int> H(13);
    H.addPair("IND", 20);
    H.addPair("PAK", 10);
    H.display();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM