0

I am simply not able to compile. All the codes worked fine when they were all in one file. The only thing I need help with is how do I separate them into implementation files, driver file, and header file correctly without compilation errors such as unresolved external symbol LINK2019 error.

Thank you for your time and help.

hashTable.h

#ifndef SINHASHTABLE_H
#define SINHASHTABLE_H

#include <iostream>
#include <string>

using namespace std;

template<typename K, typename V>
class HashNode
{
public:
    V value;
    K key;
    HashNode(K key, V value);
};

template<typename K, typename V>
class HashMap
{
    HashNode<K, V>** arr;
    int capacity;
    int size;
    HashNode<K, V>* dummy;

public:
    HashMap();
    int hashFunction(K key);
    void insertNode(K key, V value);
    V deleteNode(K key);
    V getValue(K key);
    int sizeofMap();
    bool isEmpty();
    void display();
};

#endif

hashTable.cpp

#include <iostream>

#include "hashTable.h"
using namespace std;

static const int MAX_CAPACITY = 20;

template<typename K, typename V>
HashNode<K,V>::HashNode(K key, V value)
{
    this->key = key;
    this->value = value;
}

template<typename K, typename V>
HashMap<K,V>::HashMap()
{
    capacity = MAX_CAPACITY;
    size = 0;
    arr = new HashNode<K, V>*[capacity];

    for (int n = 0; n < capacity; n++)
    {
        arr[n] = nullptr;
    }

    //dummy = new HashNode<K, V>(-1, -1);
}

//Generate hashIndex given Key
template<typename K, typename V>
int HashMap<K,V>::hashFunction(K key)
{
    return key % capacity;
}

//Insert Item
//Check for collisions when same key gave same hashIndex
//If collision occur, search for another spot on Table
template<typename K, typename V>
void HashMap<K, V>::insertNode(K key, V value)
{
    if (size == capacity)
    {
        cout << "Hash is full!";
        return;
    }

    HashNode<K, V>* temp = new HashNode<K, V>(key, value);

    int hashIndex = hashFunction(key);

    while (arr[hashIndex] != nullptr
        && arr[hashIndex]->key != key
        && arr[hashIndex]->key != -1)
    {
        hashIndex = (hashIndex + 1) % capacity;
    }

    if (arr[hashIndex] == nullptr || arr[hashIndex]->key == -1)
        size++;

    arr[hashIndex] = temp;
}

template<typename K, typename V>
V HashMap<K, V>::deleteNode(K key)
{
    if (size == 0)
    {
        cout << "Hash is Empty!";
    }

    int hashIndex = hashFunction(key);

    while (arr[hashIndex] != nullptr)
    {
        if (arr[hashIndex]->key == key)
        {
            HashNode<K, V>* temp = arr[hashIndex];
            arr[hashIndex] = dummy;

            size--;
            return temp->value;
        }

        hashIndex = (hashIndex + 1) % capacity;
    }

    return NULL;
}

template<typename K, typename V>
V HashMap<K, V>::getValue(K key)
{
    int hashIndex = hashFunction(key);
    int counter = 0;

    while (arr[hashIndex] != nullptr)
    {
        if (counter + 1 > capacity)
            return NULL;
        if (arr[hashIndex]->key == key)
        {
            return arr[hashIndex]->value;
        }

        hashIndex = (hashIndex + 1) % capacity;
    }

    cout << "***Value in Key: " << key;
    cout << " : Not Found!***" << endl;
    return NULL;
}

template<typename K, typename V>
int HashMap<K, V>::sizeofMap()
{
    return size;
}

template<typename K, typename V>
bool HashMap<K, V>::isEmpty()
{
    if (size == 0)
    {
        return true;
    }

    return false;
}

template<typename K, typename V>
void HashMap<K, V>::display()
{
    for (int n = 0; n < capacity; n++)
    {
        if (arr[n] != nullptr && arr[n]->key != -1)
            cout << "key = " << arr[n]->key
            << " value = " << arr[n]->value << endl;
    }
}

testDriver.cpp

#include "hashTable.h"

using namespace std;

int main()
{
    cout << "Key: StudentID \t Value: StudentName" << endl;

    HashMap<int, string>* a = new HashMap<int, string>;
    a->insertNode(123, "Aaron");
    a->insertNode(456, "Sarah");
    a->insertNode(789, "Anthony");
    a->display();
    cout << "Current Size: " << a->sizeofMap() << endl;

    cout << "\nOverriding Key:123 w/ Tiffany" << endl;
    a->insertNode(123, "Tiffany");
    a->display();
    cout << "Current Size: " << a->sizeofMap() << endl;

    cout << "\nDeleting Key:456 w/ Value:Sarah" << endl;
    a->deleteNode(456);
    a->display();
    cout << "Current Size: " << a->sizeofMap() << endl;

    cout << "\nThe value in Key:123 is " << a->getValue(123);
    cout << "\nThe value in Key:789 is " << a->getValue(789);
    cout << endl;

    cout << "********************************" << endl;
    cout << "\nTest 2 for tempalte: <int,int>" << endl;
    cout << "\nKey: Number \t value: Number" << endl;
    HashMap<int, int>* h = new HashMap<int, int>;
    h->insertNode(1, 1);
    h->insertNode(2, 2);
    h->insertNode(2, 3);
    h->display();
    cout << "Current Size: " << h->sizeofMap() << endl;
    
    cout << "\nThe value in Key:2 is " << h->getValue(2) << endl;

    cout << "\nDeleting Key:2 w/ Value:3" << endl;
    h->deleteNode(2);
    h->display();
    cout << "Current Size: " << h->sizeofMap() << endl;

    cout << "\nIs the Table Empty? " << h->isEmpty() << endl;

    cout << "\nDeleting All Nodes" << endl;
    h->deleteNode(1);
    cout << "Is the Table Empty? " << h->isEmpty() << endl;
    return 0;
}

I get the unresolved external symbol error from window visual studio and minGW C++ compiler. enter image description here

Zin
  • 1
  • 1
    `using namespace std;` [is a bad practice](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) normally, doing it in a header file is double as bad. – Some programmer dude Apr 14 '21 at 07:21
  • And before future questions, please take some time to take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). And never post images of error messages (or any text for that matter), copy-paste them (in full and complete) as text into your questions. – Some programmer dude Apr 14 '21 at 07:23

0 Answers0