【发布时间】:2018-04-14 07:57:14
【问题描述】:
创建了一个模板类,将字符串散列为 0 - 999 3 种不同方式的整数。我正在尝试比较散列值和索引值,当它们不同时添加到计数中,然后返回该数字以获得冲突总数。我的问题是我是否正确地执行了此操作,因为我只是在猜测我何时将所有这些放在一起。
代码:
#include <string>
#include <list>
template<typename T>
class Hash
{
protected:
// Capacity of the hash table
static const size_t SIZE = 1000;
// Defines an entry in the hash table
class Entry
{
public:
std::string key;
T value;
bool used;
Entry()
{
used = false;
value = T();
}
};
// The hash table entries
Entry entries[SIZE];
// Hash function #1
size_t hash1(const std::string& k) const;
// Hash function #2
size_t hash2(const std::string& k) const;
// Hash function #3
size_t hash3(const std::string& k) const;
// Calculate the hash of a given key
// TODO: change this to use the desired hash function
size_t hash(const std::string& k) const
{
return hash1(k);
}
// Perform linear probing on the given key and index to get index
size_t probe(const std::string& k, size_t i) const;
public:
// Access data item in hash for the given key
T& operator[](const std::string& k);
void print() const
{
for (size_t i = 0; i < SIZE; i++)
std::cout << i << "-" << entries[i].used << "-" << entries[i].key
<< "-" << entries[i].value << std::endl;
}
size_t collision(const std::string& k) const;
};
template<typename T>
size_t Hash<T>::hash1(const std::string& k) const
{
int index = 0;
for (size_t i = 0; i < k.size(); i++)
index += k[i];
return index % SIZE;
}
template<typename T>
size_t Hash<T>::hash2(const std::string& k) const
{
int index = 0;
for (size_t i = 0; i < k.size(); i++)
{
index += (k[i] + 27 * k[i] + 729 * k[i]);
}
return index % SIZE;
}
template<typename T>
size_t Hash<T>::hash3(const std::string& k) const
{
int index = 0;
for (size_t i = 0; i < k.size(); i++)
{
index += 37 * index + k[i];
}
return index % SIZE;
}
template<typename T>
size_t Hash<T>::probe(const std::string& k, size_t i) const
{
int index = i;
int count = 0;
while (entries[index].used && entries[index].key != k && count < SIZE)
index = (index + 1) % SIZE;
return index;
}
template<typename T>
T& Hash<T>::operator[](const std::string& k)
{
int index = hash(k);
if (entries[index].used && entries[index].key != k)
index = probe(k, index);
if (!entries[index].used)
{
entries[index].key = k;
entries[index].used = true;
}
return entries[index].value;
}
template<typename T>
size_t Hash<T>::collision(const std::string& k) const
{
int count = 0;
for (int j = 0; j < SIZE; j++)
{
if (j == entries[j].value)
{
count++;
}
}
return count;
}
由于列表的大小是常数 1000,因此索引值始终为 0 到 999。知道这一点,如果我将该数字与散列值 (entries[j].value) 进行比较并且它们是相同的,那么我知道值是相同的并且发生了冲突,所以我可以添加到计数中。
我正在尝试这种方式,因为我的教授说“你可以 通过检查哈希表中的每个条目并将存储的键值的哈希值与表中的索引进行比较来确定这一点。”老实说,我不确定他的意思。我要提前道歉,因为我有强烈的感觉这是完全错误的。
【问题讨论】:
-
我想他是想比较
index == hash(entries[index].key) -
你描述的对我来说听起来不错。键的散列告诉你你的值应该在表中的哪个位置。如果该值不在键的哈希建议的位置的表中,则您发生了冲突。我看到您的代码犯了两个错误:1.它没有考虑到表中的某个位置可能未使用。 2.它不计算密钥的哈希
-
其实第三个错误?为什么要传入
k? -
我投票结束这个问题,因为它属于codereview.stackexchange.com