问题:在哈希表中打印项目时,非顶级项目无法正确打印。我从文本文件中逐行添加项目。首先,确定行数,然后构造散列表,其大小在文件的第一个循环中找到。
哈希构造函数
hash::hash(unsigned int tSize)
{
this->tableSize = tSize;
hashTable.resize(tableSize);
for (int i = 0; i < tableSize; i++)
{
hashTable[i] = new item;
hashTable[i]->firstLetters = "__";
hashTable[i]->str = "____";
hashTable[i]->next = NULL;
}
}
添加项目、设置值并打印它们
void hash::add(std::string key)
{
int index = hafn(key);
if (hashTable[index]->str == "____")
{
hashTable[index]->str = key;
setFirstLetters(index,key[0],key[1]);
}
else
{
item *iter = hashTable[index];
item *n_ptr = new item;
n_ptr->str = key;
setFirstLetters(n_ptr, key[0], key[1]);
n_ptr->next = NULL;
while (iter->next != NULL)
{
iter = iter->next;
}
iter->next = n_ptr;
}
}
void hash::setFirstLetters(item *n_ptr, char a, char b)
{
n_ptr->firstLetters[0] = a;
n_ptr->firstLetters[1] = b;
}
void hash::setFirstLetters(int index, char a, char b)
{
hashTable[index]->firstLetters[0] = a;
hashTable[index]->firstLetters[1] = b;
}
void hash::print()
{
int num;
for (int i = 0; i < tableSize; i++)
{
num = numInIndex(i);
printer(num, i);
if (num > 1)
{
int c = 0;
for (int j = num - 1; j > 0; j--)
{
printer(c, num, i);
c++;
}
}
}
}
void hash::printer(int num, int i)
{
item *iter = hashTable[i];
cout << "-------------------------------" << endl;
cout << "index = " << i << endl;
cout << iter->str << endl;
cout << iter->firstLetters << endl;
cout << "# of items = " << num << endl;
cout << "-------------------------------" << endl;
cout << endl;
}
void hash::printer(int numIn, int num, int i)
{
item *iter = hashTable[i];
for (int j = 0; j < numIn; j++)
{
iter = iter->next;
}
cout << "-------------------------------" << endl;
cout << "index = " << i << endl;
cout << iter->str << endl;
cout << std::flush;
cout << iter->firstLetters << endl; //this does not work, though the pointer is pointing to the correct values
//printf("%s\n", iter->firstLetters.c_str()); //this works, even without flushing
cout << "# of items = " << num << endl;
cout << "-------------------------------" << endl;
cout << endl;
}
struct item
{
std::string str;
std::string firstLetters;
item *next;
};
问题是firstLetters
打印不正确。 firstLetters
设置正确。但是,在第三级和更高级别的项目中(即,使用相同的哈希索引),firstLetters
根本不打印。
为了更清楚,这里是一个输出示例:
-------------------------------
index = 15
will
wi
# of items = 3
-------------------------------
-------------------------------
index = 15
will
wi
# of items = 3
-------------------------------
-------------------------------
index = 15
good
# of items = 3
-------------------------------
请注意,在“添加项目、设置值和打印它们”标题下,在方法hash::add(std::string key)
中,我使用setFirstLetters()
访问内部元素std::string firstLetters
而无需先初始化它们。本质上,这会导致这些值的任何更改丢失。在打印值时访问iter->firstLetters
时,无法访问实际数据。为了避免这种未定义的行为,我在尝试更改它们之前 更改了 的定义hash::add(std::string key)
以设置 的值。firstLetters
的新定义hash::add()
void hash::add(std::string key)
{
int index = hafn(key);
if (hashTable[index]->str == "____")
{
hashTable[index]->str = key;
setFirstLetters(index,key[0],key[1]);
}
else
{
item *iter = hashTable[index];
item *n_ptr = new item;
n_ptr->firstLetters = "__"; //here
n_ptr->str = key;
setFirstLetters(n_ptr, key[0], key[1]);
n_ptr->next = NULL;
while (iter->next != NULL)
{
iter = iter->next;
}
iter->next = n_ptr;
}
}
添加此行可修复输出。
这是新的输出:
-------------------------------
index = 15
will
wi
# of items = 3
-------------------------------
-------------------------------
index = 15
will
wi
# of items = 3
-------------------------------
-------------------------------
index = 15
good
go
# of items = 3
-------------------------------
这种类型的行为算作“未定义的行为”。这里有几个移动部件,这种行为的唯一原因是由于缺乏初始化。如果std::cout
失败但printf()
没有失败,请确保在尝试访问任何成员/变量之前对其进行初始化。在使用的特定情况下std::string
,[]
操作符只有在正常初始化后,使用=
操作符或其他成员函数才能正常工作std::string
。