哈希表打印和插入功能

时间:2017-11-16 02:46:27

标签: c++ hashtable

我正在编写哈希表函数,它所拥有的数据来自文本文件。文本文件具有四位数的学生ID和带有嵌入空格的名称。问题是insert函数没有从文件中获取第一行。我运行程序,当我测试它时,文件中的第一个学生没有出现。我通过输入他们的ID来检查其余的学生名字,然后输出他们的名字。此外,它不会输出从文件中获取的全名,只是第一个。如果我从文件中查找chris campos,我会输入它的四位数ID,但只输出chris而不是chris campos。

如果你想看到完整的代码,我会编辑帖子,但我相信错误应该在我发布的代码中。我认为代码是正确的,但我想看看其他人是否可以看到错误或我如何改进它。

另外,我很好奇,我正在使用链接来处理碰撞。如何让程序输出桶中具有相同四位数ID的所有名称。如果两个名称具有相同的ID,当用户输入ID时,如何使程序输出两个名称。

2301 Robb Arredondo 
5401 Chris Campos
6305 Yogi Bear
9108 Yoshi Man 
0310 John Du
1812 Maria Yu
4318 Power Ranger
7122 Bob Chan
8225 Will Boo
5324 Ghost Lee
0134 Mary Su 
2150 Jane Mary
1100 Gary Campos 
2305 Alan Kong 
3420 Bill Nye 
5608 Alex Garcia 
9112 Goku Nani 
6750 Paul Avalos 
1220 Jason Noni 
9005 Oscar Roger 
6550 Geo Qwerty
1112 Mini Me
2315 Garfield Beria
4201 Just Saying

以下是我的程序从文件中获取数据的方式:

HashTable hashtable;
std::ifstream file("students.txt");
int option;
std::string studentID;
std::string studentName;
std::string line;

if (!file.is_open())
{
    std::cout << "Error in opening file\n";
}
else
{
    while (std::getline(file, line))
    {
        file >> studentID >> studentName;
        hashtable.Insert(studentID, studentName);
    }

    file.close();
}

这是我的插入函数..

void HashTable::Insert(std::string ID, std::string name)
{
    int location = Hash(ID, tableSize);

    if (listofStudents[location]->m_idNum == "empty")
    {
        listofStudents[location]->m_idNum = ID;
        listofStudents[location]->m_Name = name;
    }
    else
    {

        Student* ptr = listofStudents[location];
        Student* newStudent = new Student;
        newStudent->m_Name = name;
        newStudent->m_idNum = ID;
        newStudent->next = NULL;

        while (ptr->next != NULL)
        {
            ptr = ptr->next;
        }
        ptr->next = newStudent;
    }

}

这是我的检索功能......

void HashTable::Retrieve(std::string ID)
{
int location = Hash(ID, tableSize);
Student* ptr;

for (ptr = listofStudents[location]; ptr; ptr = ptr->next)
{
    if (ptr->m_idNum == ID)
    {
        std::cout << "--------------------\n";
        std::cout << "Name of Student: " << ptr->m_Name << std::endl;
        std::cout << "---------------------\n";
    }
    else
        std::cout << "No Student Found\n";
}
}

如果你想看看散列技术是如何工作的,那么这是我的散列函数。它将字符串转换为int。我使用字符串的原因是因为我需要使用字符串进行赋值。

int HashTable::Hash(const std::string& key, int tablesize)
{
    int hashVal = 0;
    for (int i = 0; i < key.length(); i++)
    {
        hashVal =  37 * hashVal + key[i];
    }
    hashVal %= tablesize;

    if (hashVal < 0)
        hashVal += tablesize;

    return hashVal;
}

2 个答案:

答案 0 :(得分:0)

罪魁祸首在这里:

file >> studentID >> studentName;

这不符合你的想法。我建议将line转储到std::stringstream,然后从中提取字段:

while (std::getline(file, line))
{
    std::stringstream ss(line);
    std::string ID;
    std::string firstName;
    std::string lastName;

    ss >> ID >> firstName >> lastName;
    hashtable.Insert(studentID, firstName + " " + lastName);
}

请注意,您尝试将名称转储为单个字符串,但实际上有两个字段(名字和姓氏),因此您需要两个变量。您可以将它们组合成一个字符串。

P.S。在哈希表中,STL hashmap实现(std::unordered_map)是你的朋友。

答案 1 :(得分:0)

你的问题在这里:

while (std::getline(file, line))
{
    file >> studentID >> studentName; // This only read the id and the first name
    hashtable.Insert(studentID, studentName);
}

你应该尝试:

file >> studentID >> firstname >> lastname;
file.ignore(); // this will pass the EOL character