0

I'm currently writing a program that uses hash tables searching through ship records. It's based off a text file I named "shipRecords.txt" containing the following:

  1009 1 "Royal Queen"     2015 160
 1010   2  "Carnival"        2016  1600
 1019  1  "Ocean King"       2013  110
 1029 2 "Royal Prince"     2012 2000
 1039 2 "Royal Princess"  2010 2100
 1014 2 "Royal Caribbean" 2016 1600

The thing I'm having trouble with is displaying the records in the format as shown in the expected output below.

The displays are consisted of in 3 functions: displayAll(), displayOne(), and deleteOne().

displayAll()- For each bucket, it first displays a bucket number and then lists all the records in the bucket. The system will display all records in a listing.

displayOne()- With a given serial number, the bucket # and information of the ship is displayed.

deleteOne()- Delete the record of the given serial number.

I have never used hash tables before and still new to C++, but if anyone could help me out or give me some hints to achieve the expected output, I would really appreciate it!

Test Code in progress...

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;

struct ShipRecord
{
    int serialNum;
    int shipType;
    string name;
    int year;
    int cap;
    ShipRecord* link;
};

const int SIZE = 10;
class HashMgr
{
    ShipRecord* hashTable[SIZE] = {nullptr};

public:
    HashMgr()
    {
        string line;
        ifstream inputFile;
        inputFile.open("shipRecords.txt");

        if(inputFile.is_open())
        {
            while (!inputFile.eof())
            {
                getline(inputFile, line);
                addInfo(line);
            }
            inputFile.close();
        }
    }

    ~HashMgr()
    {
        /// To DO: Add your code here to ensure no memory leak occurs
        for (int i = 0; i < SIZE; ++i)
        {
            while (hashTable[i] != nullptr)
            {
                ShipRecord* tempRecord = hashTable[i];
                hashTable[i] = tempRecord->link;
                delete tempRecord;
            }
        }
    }

    HashFunc(int serialNum)
    {
        return serialNum % SIZE;
    }

    void addInfo(string line)
    {
        vector<string> tokens;
        stringstream check1(line);
        string inter;

        cout << endl << "PARSING STRING:\"" << line << "\"" << endl;
        cout << "---------------"<< endl;

        while(getline(check1, inter, '\"'))
        {
            tokens.push_back(inter);
        }

        for(unsigned int i = 0; i < tokens.size(); i++)
            cout << tokens[i] << endl;

        cout << "---------------"<< endl;
    }

    void displayOne(int serialNum)
    {
        int bucket = HashFunc(serialNum);
        ShipRecord* tempRecord = hashTable[bucket];

        while(tempRecord != nullptr && tempRecord->serialNum != serialNum)
        {
            tempRecord = tempRecord->link;
        }
        if(tempRecord == nullptr)
        {
            cout << serialNum << " <- This ship record does not exist." << endl;
        }
        else if(tempRecord->serialNum == serialNum)
        {
            cout << tempRecord->serialNum << setw(10)
                 << tempRecord->shipType << setw(10)
                 << tempRecord->name << setw(10)
                 << tempRecord->year << setw(10)
                 << tempRecord->cap << setw(10) << endl;
        }
    }

    void displayAll()
    {
        for(int i = 0; i < SIZE; i++)
        {
            ShipRecord* tempRecord = hashTable[i];

            while(tempRecord != nullptr)
            {
                cout << tempRecord->serialNum << setw(10)
                     << tempRecord->shipType << setw(10)
                     << tempRecord->name << setw(10)
                     << tempRecord->year << setw(10)
                     << tempRecord->cap << setw(10) << endl;
                     tempRecord = tempRecord->link;
            }
        }
    }

    void deleteOne(int serialNum)
    {
        cout << "Ship record " << serialNum << " deleted!" << endl;

        int bucket = HashFunc(serialNum);
        ShipRecord* tempRecord = hashTable[bucket];
        ShipRecord* link;

        while(tempRecord != nullptr && tempRecord->serialNum != serialNum)
        {
            link = tempRecord->link;
            free(tempRecord);
            tempRecord = link;
        }
    }
};

int main()
{
    HashMgr hm;

    cout << "displayAll()" << endl << endl;
    hm.displayAll();

    cout << "displayOne()" << endl << endl;
    hm.displayOne(1009);
    hm.displayOne(1010);
    hm.displayOne(1019);
    hm.displayOne(1029);
    hm.displayOne(1039);
    hm.displayOne(1014);
    hm.displayOne(1008); /// Prompt a message to that the record does not exist

    hm.deleteOne(1009);
    hm.deleteOne(1039);

    cout << "displayAll()" << endl << endl;
    hm.displayAll();

    return 0;
}

Current Output

PARSING STRING:   1009 1 "Royal Queen"     2015 160

PARSING STRING:  1010   2  "Carnival"        2016  1600

PARSING STRING:  1019  1  "Ocean King"       2013  110

PARSING STRING:  1029 2 "Royal Prince"     2012 2000

PARSING STRING:  1039 2 "Royal Princess"  2010 2100

PARSING STRING:  1014 2 "Royal Caribbean" 2016 1600

displayAll()

1010    2       Carnival        2016    160
1014    2       Royal Caribbean 2016    160
1009    1       Royal Queen     2015    16
displayOne()

1009    1       Royal Queen     2015    16
1010    2       Carnival        2016    160
1019 <- This ship record does not exist.
1029 <- This ship record does not exist.
1039 <- This ship record does not exist.
1014    2       Royal Caribbean 2016    160
1008 <- This ship record does not exist.
displayAll()

1010    2       Carnival        2016    160
1014    2       Royal Caribbean 2016    160
1009    1       Royal Queen     2015    16

Expected Output

PARSING STRING:"  1009 1 "Royal Queen"     2015 160"
---------------
1009 
1
Royal Queen
2015 
160
---------------

PARSING STRING:" 1010   2  "Carnival"        2016  1600"
---------------
1010   
2
Carnival
2016  
1600
---------------

PARSING STRING:" 1019  1  "Ocean King"       2013  110"
---------------
1019  
1
Ocean King
2013  
110
---------------

PARSING STRING:" 1029 2 "Royal Prince"     2012 2000"
---------------
1029 
2
Royal Prince
2012 
2000
---------------

PARSING STRING:" 1039 2 "Royal Princess"  2010 2100"
---------------
1039 
2
Royal Princess
2010 
2100
---------------

PARSING STRING:" 1014 2 "Royal Caribbean" 2016 1600"
---------------
1014 
2
Royal Caribbean
2016 
1600
---------------

displayAll()
Bucket #0
   1010 2 "Carnival"         2016  1600
Bucket #4
   1014 2 "Royal Caribbean"  2016  1600
Bucket #9  
   1009 1 "Royal Queen"      2015   160
   1019 1 "Ocean King"       2013   110
   1029 2 "Royal Prince"     2012  2000
   1039 2 "Royal Princess"   2010  2100

displayOne()
Bucket #0
   1010
Bucket #4
   1014
Bucket #8
   1008 <- This record does not exist!
Bucket #9  
   1009
   1019
   1029
   1039

displayAll()
Bucket #0
   1010 2  "Carnival"        2016  1600
Bucket #4
   1014 2 "Royal Caribbean"  2016  1600
Bucket #9  
   1019 1  "Ocean King"      2013   110
   1029 2 "Royal Prince"     2012  2000

Deleted ship record (1009)!
Deleted ship record (1039)!
Orion98
  • 91
  • 5
  • displayAll: `ShipRecord * hashTable = nullptr; while (hashTable != nullptr)` ..why do you expect this function to print anything? – 463035818_is_not_a_number Nov 21 '19 at 19:34
  • *I have never used hash tables before and still new to C++,* -- `std::unordered_map` is the hash-table in C++. – PaulMcKenzie Nov 21 '19 at 19:35
  • @formerlyknownas_463035818; I honestly don't know what I'm doing and I'm trying various things to get my program to work properly at the moment. – Orion98 Nov 21 '19 at 19:38
  • @PaulMcKenzie; I'll give that a shot. – Orion98 Nov 21 '19 at 19:38
  • Basically, you have to provide the hash function, but I don't see one in your code. Also [read this](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – PaulMcKenzie Nov 21 '19 at 19:39
  • I updated my code according to the inputs I received. I'm still experiencing some issues as shown in my updated output and like to get some additional help on how to fix it. – Orion98 Dec 05 '19 at 00:20

1 Answers1

1

There are several things which do not work:

  1. Function displayAll will not do anything because hashtable variable is initialized by nullptr, and the rest is supposed to work when hashptr is NOT nullptr

  2. Function displayOne will ALWAYS print "The record does not exist" because there is no other way to exit the function. If your serialNum is less that SIZE (constant 10), and your passed parameters are higher than 1000, you will not get anything else printed.

  3. I am not sure C++ compiler will let you code function definitions without return value type; i.e. you will need to code int displayOne(int ...) instead of displayOne(int ...)

I would fix these before going any further.