2017-11-12 5 views
1

C++のハッシュテーブルを初めて使用しています。このプログラムを使ってファイルからデータを読み込みました。 4桁の生徒IDと埋め込みスペースを持つ名前。プログラムが実行されると、ユーザーはオプション1または2を入力し、オプション1を選択すると、学生IDを入力して学生IDを渡すか、名前がないと言います。文字列キーを使用したC++ハッシュテーブル

これはテキストファイルからのもので、このようにテキストファイルには表示されません。生徒IDは、最初の列に名前が付いています。

2300 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 
1200 Jason Noni 
9005 Oscar Roger 
6550 Geo Qwerty 
1112 Mini Me 
2315 Garfield Beria 
4201 Just Saying 
2399 Help Me 

本は、ハッシュテーブルをソートするために、整数を使用していますが、私は、ハッシュテーブルをソートするためのキーとして文字列変数を使用する必要があります。問題は、生徒IDの最後の2桁がハッシュテーブルをソートし、生​​徒を正しいスロットに入れることです。私はこれを行う方法を知らないし、文字列変数にする必要があります。私はintを使うことはできません。私はASCII値を使ってハッシュテーブルをソートすることができますが、ここでは適用できないと思います。

また、デストラクタに問題があります。オプション2を押してプログラムを終了すると、クラッシュします。私はそれのためのコードをコメントアウトした。私は連鎖を使用して、リンクリストで衝突を解決しています。

私はatoi関数を使用して文字列を整数に変換するところで問題を解決しようとしましたが、学生の正しい名前が返されません。最後に、このハッシュテーブルでベクトルを使用できますか?代わりのメンバーアレイのように、その種類あなたのデストラクタで

#pragma once 
#include <string> 

struct Student 
{ 
std::string m_idNum; 
std::string m_Name; 
Student *next; 
}; 

#pragma once 
#include "Student.h" 
#include <iostream> 

class HashTable 
{ 

    private: 
    int Hash(const std::string&); 
    static const int tableSize = 100; 
    Student* listofStudents[tableSize]; 

    public: 
     HashTable(); 
    ~HashTable(); 
     void Insert(std::string ID, std::string name); 
     void Retrieve(std::string ID); 
}; 

#include "HashTable.h" 


HashTable::HashTable() 
{ 
    for (int i = 0; i < tableSize; i++) 
    { 
     listofStudents[i] = new Student; 
     listofStudents[i]->m_Name = " "; 
     listofStudents[i]->m_idNum = " "; 
     listofStudents[i]->next = NULL; 
    } 
} 

HashTable::~HashTable() 
{ 
    /*for (int i = 0; i < tableSize; i++) 
    { 
     Student* ptr = listofStudents[i]; 
     while (ptr != NULL) 
     { 
      Student* prev = ptr; 
      ptr = ptr->next; 
      delete prev; 
     } 
    } 

    delete[] listofStudents;*/ 
} 

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

    if (listofStudents[location]->m_Name == "") 
    { 
     listofStudents[location]->m_Name = name; 
     listofStudents[location]->m_idNum = ID; 
    } 
    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); 
    bool foundStudent; 
    std::string name; 

    Student* ptr = listofStudents[location]; 
    while (ptr != NULL) 
    { 
     if (ptr->m_idNum == ID); 
     { 
      foundStudent = true; 
      name = ptr->m_Name; 
     } 
     ptr = ptr->next; 
    } 

    if (foundStudent == true) 
    { 
     std::cout << "------------------------------\n"; 
     std::cout << " Name of Student: " << name << std::endl; 
     std::cout << "------------------------------\n"; 
    } 
    else 
    { 
     foundStudent = false; 
     std::cout << "---------------------------------\n"; 
     std::cout << " No Student exist with that ID" << std::endl; 
     std::cout << "----------------------------------\n"; 
    } 

} 

int HashTable::Hash(const std::string& key) 
{ 
    int sum = 0; 

    for (int index = 0; index < key.length(); index++) 
     sum = 39 * sum + key[index]; 

    sum %= tableSize; 

    if (sum <0) 
     sum += tableSize; 

    return sum; 
} 



    #include <fstream> 
#include "HashTable.h" 

int Menu(); 
void FindStudent(HashTable&); 

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

    while (file >> studentID >> studentName) 
    { 
     hashtable.Insert(studentID, studentName); 
    } 

    do 
    { 
     option = Menu(); 

     switch (option) 
     { 
      case 1: FindStudent(hashtable); 
      break; 

      case 2: 
      break; 
     } 

    } while (option != 2); 

    return 0; 
} 

int Menu() 
{ 
    int choice; 

    std::cout << " 1.)Find Student by ID\n"; 
    std::cout << " 2.)Exit\n"; 
    std::cout << " Enter option:"; 
    std::cin >> choice; 

    return choice; 
} 

void FindStudent(HashTable& hash) 
{ 
    std::string fourdigit; 

    std::cout << " Enter Students four digit ID: "; 
    std::cin >> fourdigit; 

    std::atoi(fourdigit.c_str()); 

    hash.Retrieve(fourdigit); 
} 
+0

文字列ではなく、int型のIDを取得するのはなぜですか?4桁であることを考えれば、 – PaulMcKenzie

+0

文字列を使用する必要があるためです。割り当てのその部分。 – Fus10n

+0

コードを編集して問題の[mcve]にしてください。あなたの現在のコードには、問題の周辺にあるものが多く含まれています。通常、最小単位のサンプルは良い単位テストと似ています。 –

答えて

0

delete[] listofStudents;が間違っているようStudent*とそのベクトルは、それがクラッシュの原因となります。

hastableを実装していますが、studentをリンクリストとして実装していますが、このプログラムでは使用できません。 Student *nextメンバーをStudent構造体と関連するすべてのコードから削除し、delete[] listofStudents;を以下のように変更すると動作します。

//delete[] listofStudents;//Second deletion, this is wrong. 
for (int i = 0; i < tableSize; i++) 
{ 
    delete listofStudents[i]; 
} 
+0

ハッシュテーブルの衝突を解決するためにリンクリストを使用する必要はありませんか? – Fus10n

関連する問題