首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >固定大小散列映射的实现

固定大小散列映射的实现
EN

Code Review用户
提问于 2014-10-23 00:30:46
回答 1查看 6.2K关注 0票数 10

我试图仔细研究我的算法和数据结构,并编写了一个固定大小的散列图,假设键和值都是整数。这是对实际情况的重大简化,应该是这样的。任何关于bug、最佳实践、风格的评论都很受欢迎。

代码语言:javascript
复制
#include <vector>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <assert.h>
#define SIZE 10

class HashEntry {
public:
    int _k;
    int _v;
    HashEntry(int k, int v) : _k(k), _v(v) {};
};

class HashMap {
private:
    std::vector<HashEntry> buckets[SIZE];
    int hashFunc(int key);
    std::vector<HashEntry>& getBucket(int key);

public:
    bool keyExists(int k);
    HashEntry get(int k);
    bool put(int k, int v);
    bool remove(int k);
};

int HashMap::hashFunc(int key) {
    return key % SIZE;
}

std::vector<HashEntry>& HashMap::getBucket(int key) {
    if (key < 0) {
        throw std::runtime_error("key should be >= 0");
    }
    return buckets[hashFunc(key)];
}

HashEntry HashMap::get(int k) {
    std::vector<HashEntry>& bucket = getBucket(k);
    for (HashEntry entry : bucket) {
        if (entry._k == k) {
            return entry;
        }
    }
    throw std::runtime_error("Key not found");
}
bool HashMap::keyExists(int k) {
    std::vector<HashEntry>& bucket = getBucket(k);
    for (HashEntry entry : bucket) {
        if (entry._k == k) {

            // key already exists
            return true;
        }
    }
    return false;
}

bool HashMap::put(int k, int v) {
    std::vector<HashEntry>& bucket = getBucket(k);
    if (keyExists(k)) return false;
    bucket.push_back(HashEntry(k, v));
    return true;
}

bool HashMap::remove(int k) {
    std::vector<HashEntry>& bucket = getBucket(k);
    if (!(keyExists(k))) return false;
    for (auto itr = bucket.begin(); itr != bucket.end(); ++itr) {
        HashEntry entry = static_cast<HashEntry>(*itr);
        if (entry._k == k) {
            bucket.erase(itr);
            return true;
            break;
        }
    }
    return false;
}

int main() {
    HashMap map;
    for (int i=0; i < 10; ++i) {
        assert(map.put(i, i*10));
    }
    for (int i=0; i < 10; ++i) {
        assert(map.keyExists(i) == true);
    }
    assert(map.keyExists(0) == true);
    assert(map.get(0)._v == 0);
    assert(map.remove(0) == true);
    assert(map.remove(0) == false);
    assert(map.keyExists(0) == false);

    bool exceptionThrown = false;
    try {
        map.get(0);
    } catch (std::exception &e) {
        exceptionThrown = true;
    };
    assert(exceptionThrown);
    return 1;
}
EN

回答 1

Code Review用户

发布于 2014-10-23 01:58:13

科尔宾给出了一个相当全面的答案。

不过,我立即注意到的部分是可访问的HashEntry类,以及它是如何通过使用get()方法泄漏的。

散列是键到值的映射。您的put方法是bool put(int,int),对称的是,get应该是int get(int)

get返回不应该释放的HashEntry。因为你这样做,人们可能会搞砸你的条目,因为_k_v也是公开的。

get应该返回int,并且您应该建立一个协议,允许您确定密钥是否不存在(返回0?)或者它是否存在( keyExists(int)可以是一个双重检查)。

票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/67625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档