【发布时间】:2021-03-14 11:07:12
【问题描述】:
我正在尝试使用 STL 对列表在 C++ 中实现哈希表。初始 maxSize 我设置为 1,并且我想在其 currentSize 大于最大容量的 75% 时将哈希表的大小增加两倍。我收到错误“无法取消引用结束列表运算符”。这是我的实现:
template<class V>
class HashTable {
public:
int currentSize;
int maxSize;
std::list<std::pair<std::string, V> > *arr;
HashTable() {
this->currentSize = 0;
this->maxSize = 1;
this->arr = new std::list<std::pair<std::string, V> >[maxSize];
arr->assign(maxSize, std::pair<std::string, V>());
}
~HashTable() {
delete[] arr;
}
void add(std::string key, V value) {
if (currentSize >= 0.75 * maxSize) {
rehash();
}
currentSize++;
int idx = hashFunction(key);
std::list<std::pair<std::string, int> >::iterator it = arr->begin();
std::advance(it, idx);
it = arr->erase(it);
arr->insert(it, std::pair<std::string, V> (key, value));
}
int hashFunction(std::string key) {
int total = 0;
for (int i = 0; i < key.length(); i++) {
total += int(key[i]) * pow(31, key.length() - i - 1);
}
return total % maxSize;
}
void rehash() {
maxSize *= 2;
std::list<std::pair<std::string, V> > *newArr = new std::list<std::pair<std::string, V> >[maxSize];
newArr->assign(maxSize, std::pair<std::string, V>());
for (auto it = arr->begin(); it != arr->end(); it++) {
int idx = hashFunction(it->first);
it = arr->begin();
std::advance(it, idx);
it = arr->erase(it);
newArr->insert(it, std::pair<std::string, V>(it->first, it->second));
}
delete[] arr;
arr = newArr;
}
有趣的事实是,当我对 maxSize 进行硬编码时,例如通过将其设置为 20 然后添加 2 个元素,它可以工作并输出例如"1: abc -> 123, 5: bca -> 42"。
【问题讨论】:
-
std::list<std::pair<std::string, V> > *arr;-- 为什么不std::vector<std::list<std::pair<std::string, V> >> arr;?这样您就不必进行任何手动内存管理。 -
我看到 Rule of Three 违规,但我不确定这是否是错误的原因。为什么使用手动内存管理而不是
std::vector? -
而且您似乎没有使用该数组。您只使用该数组的第一个元素。
-
int main() { HashTable<int> h1; HashTable<int> h2 = h1; }-- 那个简单的程序出现双重删除错误。