实现哈希表(rehash范围错误)
Implementing a Hash Table (rehash scope error)
我的代码中出现了一个非常奇怪的错误。这项作业是为我正在上的一门课准备的,本质上我们正在学习如何实现哈希表。我遇到的错误是,当我尝试重新安装到更大的尺寸时。以下是代码中给出问题的部分,我将更全面地解释问题是什么
if(htable->size>=htable->cap)
{
cout<<htable->cap<<endl;
HashTable tempht=*htable;
delete htable;
htable=new HashTable((tempht.cap * 2) + 1);
for (size_t i=0; i<tempht.cap; i++)
{
Node* n=tempht.table[i];
while (n!=NULL)
{
htable->add(n->item);
n=n->next;
}
}
if (htable->table[0]==NULL)
{
cout<<"HOORAY!"<<endl;
}
}
if (htable->table[0]==NULL)
{
cout<<"HOORAY!"<<endl;
}
else
{
cout<<htable->table[0]->item<<endl;
}
htable
是HashTable
变量。在HashTable
类中,它包含一个数组Node*
(节点只是我创建的对象,其中包含一个字符串和指向链中下一项的指针)。这部分代码只是试图重新散列到一个更大的表。我遇到的问题是,一旦我退出第一个if语句,我的表的第一个值就不再等于NULL(我正在运行的测试将一个没有任何内容的表重新灰成一个仍然没有任何内容但容量更大的表)。当我运行代码时,第一个htable->table[0]==NULL
通过,而第二个没有通过,尽管除了退出if语句之外没有任何更改(我的预期结果是table[0]
应该为NULL)。我最好的猜测是这是某种范围错误,但老实说,我看不出问题出在哪里。任何帮助都将不胜感激。
编辑:为了澄清,初始哈希表的容量为0(这是项目要求之一)。因此,当我试图向表中添加一个项时,会执行if语句(由于大小为0,上限为0,因此我们必须保持负载因子为1)。我可以确认,一旦表达到第一次和第二次"Hooray"检查,htable->cap
(数组的总容量)就是1,这就是它应该是的。唯一被搞砸的是bucket 0(在这种情况下,它是唯一的bucket)。无论出于何种原因,它在退出if语句之前为null,但在退出之后则不为null。
我正在发布我的整个HashTable
课程,如果你发现什么,请告诉我。
#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include "Node.h"
using namespace std;
class HashTable
{
public:
Node** table;
int size;
int cap;
HashTable (int c)
{
size=0;
cap=c;
table = new Node*[cap];
if (cap>0)
{
for (size_t i=0; i<cap; ++i)
{
table[i]=NULL;
}
}
}
~HashTable()
{
delete table;
}
size_t hash(string thing)
{
size_t total=0;
int asci;
char c;
size_t index;
for (size_t i=0; i<thing.length(); i++)
{
total=total*31;
c=thing[i];
asci=int(c);
total=asci+total;
}
index=total%cap;
cout<<"index"<<index<<endl;
system("pause");
return index;
}
void add(string thing)
{
size_t index;
index=hash(thing);
cout<<"index "<<index<<endl;
system("pause");
Node* temp=table[index];
if (temp==NULL)
{
cout<<"Here"<<endl;
system("pause");
}
else
{
cout<<"Here2"<<endl;
system("pause");
cout<<"temp"<<temp->item<<endl;
system("pause");
}
Node* n = new Node(thing);
cout<<"n"<<n->item<<endl;
system("pause");
if (temp==NULL)
{
table[index]=n;
}
else
{
while (temp->next!=NULL)
{
temp=temp->next;
}
temp->next=n;
}
size++;
}
Node* find(string search)
{
Node* n= NULL;
size_t index;
if(cap!=0)
{
index=hash(search);
Node* temp=table[index];
while (temp!=NULL)
{
if (temp->item==search)
{
n=temp;
return n;
}
}
}
return n;
}
void remove (string thing)
{
if (find(thing)==NULL)
{
return;
}
else
{
size_t index;
index=hash(thing);
Node* temp=table[index];
if (temp->item==thing)
{
table[index]=temp->next;
delete temp;
}
while (temp->next!=NULL)
{
if (temp->next->item==thing)
{
Node* temp2=temp->next;
temp->next=temp->next->next;
delete temp2;
break;
}
}
}
size--;
}
void print(ofstream &ofile)
{
for (size_t i=0; i<cap; i++)
{
Node* n=table[i];
ofile<<"hash "<<i<<":";
while (n!=NULL)
{
ofile<<" "<<n->item;
n=n->next;
}
}
}
};
好吧,这是C++,我更喜欢Java,但我会尝试一下。
问题出在上
HashTable tempht=*htable;
delete htable;
毕竟是块。
看,第一行写着"将所有成员从*htable复制到tempht"。现在tempht和htable共享它们的表内存,因为表只是一个指向构造时分配的内存的指针,而您只是复制了指针。您希望它复制表中的节点,但它并没有这样做。
所以现在在表中有两个指针值相同的不同HashTable对象。现在,当释放tempht时,析构函数对表指针调用free,从而有效地释放对象htable和tempht中的表数据。
你真正想做的是写一个复制构造函数,或者做一些类似的事情:
HashTable *tempht=htable;
htable=new HashTable((tempht->cap * 2) + 1);
for (size_t i=0; i<tempht->cap; i++)
{
Node* n=tempht->table[i];
while (n!=NULL)
{
htable->add(n->item);
n=n->next;
}
}
if (htable->table[0]==NULL)
{
cout<<"HOORAY!"<<endl;
}
delete tempht;
看看我真正做的是如何将tempht更改为指针,使用它指向旧哈希表,同时将其中的所有节点复制到新的htable对象,然后删除旧哈希表。
- 错误:未在此范围内声明'reverse'
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 错误:"imread"未在此范围内声明
- 我在范围内未声明的错误类有问题
- 未在此范围内声明错误 'xy'
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 运行时错误:矢量下标超出范围:正在检查空集
- 错误:'[' 之前预期的非限定 id 和错误:'users'未在此范围内声明
- 在此范围内未声明错误"Clreol"
- "myClock"未在此范围错误中声明
- 包含来自另一个文件的函数会导致范围错误(openFoam)
- 构造中错误:未在此范围中声明"data"
- 使用基于范围的指针循环和向量时出现C++错误
- DEV C++ 第 69 行 [错误] ISO "for" 范围更改了"i"的名称查找 [-允许]
- C++ 中的类之间的数据重新循环 - 错误:'<class name>'未在此范围内声明
- 使用to_string、reverse、stoi组合的C++反转编号给出运行时错误实例超出范围
- 如何避免指针超出范围(多态性)的C++分段错误
- 代码作为 C 文件工作,但不作为C++文件,错误:'__builtin_types_compatible_p'未在此范围内声明
- 如何修复范围内的字符串声明错误
- 如何修复错误:"vreinterpretq_u32_f64"未在此范围内声明 - 在Android上使用Eigen构建