使用向量<对<字符串,int > >表示哈希表

Using a vector < pair < string, int > > to represent a hash table

本文关键字:gt lt int 哈希表 表示 向量 字符串      更新时间:2023-10-16

我正试图将哈希表表示为对<字符串,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;

我做错了什么?

由于需要内存,您实际上无法以这种方式完成容器。相反,您希望容器和插入代码更接近于经典的哈希容器设计,类似于以下内容:

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);

您需要将哈希索引模化为vector中的索引范围。例如,将vector初始化为具有1000个bucket,然后使用hashfunction(..) % 1000

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

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

请注意,您采用的哈希方法有点过于简单:尤其是对于数量较少的bucket,有可能将两个不同的哈希键控到同一bucket。也就是说,你需要处理碰撞。据我所知,处理碰撞的两种方法是

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