使用矢量<对< string,int> >表示哈希表

时间:2013-12-07 19:58:37

标签: c++ hash

我试图将哈希表表示为对的向量< string,int>。我正在使用哈希函数来返回我希望放置该对的向量索引的值。我已经能够成功创建一对并使用哈希函数索引该对的字符串。现在我知道我想把我的对放在我的向量中,我试着把它放在那里但是我的程序此时有一个分段错误。 我的哈希函数:

size_t hashfunction(const string& ident){
    unsigned hash = 0;
    for(int i = 0; i < ident.size(); ++i) {
       char c = ident[i];
       hash ^= c + 0x9e3779b9 + (hash<<6) + (hash>>2);
    }
    return hash;
}

我的主要职能:

int main(){
    vector < pair < string, int > > hashtable;
    pair <string, int> testone ("bartering", 5);

    size_t testoneindex = hashfunction(testone.first);
    hashtable[testoneindex] = testone;
    return 0;

}

此部分代码编译但在行

处产生分段错误
hashtable[testoneindex] = testone;

我做错了什么?

3 个答案:

答案 0 :(得分:1)

由于需要内存,您无法以这种方式实现容器。相反,您希望容器和插入代码更接近经典的哈希容器设计,如下所示:

typedef pair <string, int> value_t;
value_t val;
vector<list<value_t>> buckets;
buckets.resize(current_size);
auto& bucket = buckets[hashfunc(val.first) % buckets.size()];
auto itr = find_if(bucket.begin(), bucket.end(), [&](value_t const& other) {
    return other.first == val.first;
});
if (itr == bucket.end()) bucket.push_back(val);

答案 1 :(得分:1)

您需要将哈希索引模型化为vector中的索引范围。例如,初始化您的vector以拥有1000个存储桶,并使用hashfunction(..) % 1000

答案 2 :(得分:0)

您创建的std::vector<...>为空。将对象放置在此对象中的任何位置都不起作用。您需要将hashtable对象的大小调整为合适的大小,即,您需要为该对象提供桶的数量,例如,使用

std::size_t number_of_buckets = ...;
std::vector<std::pair<std::string, int> > hashtable(number_of_buckets);

请注意,您对哈希采用的方法有点过于简单化了:特别是对于较少数量的存储桶,有两个不同的哈希值可能存在于同一存储桶中。也就是说,你需要处理碰撞。处理我所知道的碰撞的两种方法是

  1. 如果已找到第一个存储桶,则确定带有密钥的新存储桶(并继续搜索新存储桶,直到找到空存储桶为止)。这种方法的主要问题是您无法真正删除对象,因为可以找到其他重新对象的对象。
  2. 在每个存储桶中使用列表,以获取使用相同存储桶的所有密钥。这种方法的另一个优点是,在实际使用存储桶之前,您不需要创建任何键或值(但是,您可以使用这些列表,但这可以相当便宜)。