implement initial version of list and rehash (rehash has issues)
This commit is contained in:
parent
261acea264
commit
62016d94a3
@ -8,19 +8,21 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class DisplayManager {
|
class DisplayManager {
|
||||||
private:
|
private:
|
||||||
HashTable<T> hashTable;
|
HashTable<T> *hashTable;
|
||||||
BinarySearchTree<std::string> bst;
|
BinarySearchTree<std::string> *bst;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DisplayManager(HashTable<T>& ht, BinarySearchTree<std::string>& bst);
|
DisplayManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst);
|
||||||
|
|
||||||
~DisplayManager();
|
~DisplayManager();
|
||||||
|
|
||||||
void displayAll() const;
|
void displayAll() const;
|
||||||
|
|
||||||
void displayTree() const;
|
void displayTree() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DisplayManager<T>::DisplayManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst) {
|
DisplayManager<T>::DisplayManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst) {
|
||||||
this->hashTable = ht;
|
this->hashTable = ht;
|
||||||
this->bst = bst;
|
this->bst = bst;
|
||||||
}
|
}
|
||||||
@ -35,9 +37,9 @@ void DisplayManager<T>::displayAll() const {
|
|||||||
std::cout << "All CPUs in the database:" << std::endl;
|
std::cout << "All CPUs in the database:" << std::endl;
|
||||||
|
|
||||||
// Iterate over the HashTable and display each CPU
|
// Iterate over the HashTable and display each CPU
|
||||||
for (int i = 0; i < hashTable.getSize(); i++) {
|
for (int i = 0; i < hashTable->getCount(); i++) {
|
||||||
if (hashTable.getItem(i) != nullptr) {
|
if (hashTable->getItem(i) != nullptr) {
|
||||||
std::cout << *(hashTable.getItem(i)) << std::endl;
|
std::cout << *(hashTable->getItem(i)) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,7 +50,7 @@ void DisplayManager<T>::displayTree() const {
|
|||||||
|
|
||||||
// Call the BST's inorder traversal method to display the tree
|
// Call the BST's inorder traversal method to display the tree
|
||||||
// TODO: Use a proper display function
|
// TODO: Use a proper display function
|
||||||
bst.inOrder([](const std::string& key) {
|
bst->inOrder([](const std::string &key) {
|
||||||
std::cout << key << std::endl;
|
std::cout << key << std::endl;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
37
HashTable.h
37
HashTable.h
@ -4,6 +4,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "HashNode.h"
|
#include "HashNode.h"
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
using std::string, std::ofstream, std::cout, std::endl;
|
using std::string, std::ofstream, std::cout, std::endl;
|
||||||
|
|
||||||
@ -50,6 +51,8 @@ public:
|
|||||||
int search(T &itemOut, const T &key, int h(const T &key, int size)) const;
|
int search(T &itemOut, const T &key, int h(const T &key, int size)) const;
|
||||||
|
|
||||||
void outputFile(const string &filename, string visit(const T &));
|
void outputFile(const string &filename, string visit(const T &));
|
||||||
|
|
||||||
|
void reHash(int h(const T &key, int size));
|
||||||
};
|
};
|
||||||
|
|
||||||
/*~*~*~*
|
/*~*~*~*
|
||||||
@ -185,4 +188,38 @@ void HashTable<T>::outputFile(const string &filename, string visit(const T &)) {
|
|||||||
outputFile.close();
|
outputFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void HashTable<T>::reHash(int h(const T &key, int size)){
|
||||||
|
|
||||||
|
int nHashSize = hashSize * 2;
|
||||||
|
|
||||||
|
nHashSize = findNextPrime(nHashSize);
|
||||||
|
|
||||||
|
HashNode<T>* nHashAry = new HashNode<T>[nHashSize];
|
||||||
|
|
||||||
|
// Goes through each bucket and puts it in the new array
|
||||||
|
T aT;
|
||||||
|
for(int i = 0; i < hashSize; i++){
|
||||||
|
if(hashAry[i].getOccupied() == 1){
|
||||||
|
aT = hashAry[i].getItem();
|
||||||
|
|
||||||
|
int nIndex = h(aT, nHashSize);
|
||||||
|
|
||||||
|
for(int j = 0; j < hashSize; j++){
|
||||||
|
if(nHashAry[nIndex].getOccupied() != 1){
|
||||||
|
nHashAry[nIndex].setItem(aT);
|
||||||
|
nHashAry[nIndex].setOccupied(1);
|
||||||
|
nHashAry[nIndex].setNumCollisions(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nIndex = (nIndex + 1) % hashSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hashAry = nHashAry;
|
||||||
|
hashSize = nHashSize;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // INC_08_TEAM_PROJECT_HASHTABLE_H
|
#endif // INC_08_TEAM_PROJECT_HASHTABLE_H
|
||||||
|
@ -7,16 +7,16 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class SearchManager {
|
class SearchManager {
|
||||||
private:
|
private:
|
||||||
HashTable<T> hashTable;
|
HashTable<T> *hashTable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SearchManager(HashTable<T> &ht);
|
SearchManager(HashTable<T> *ht);
|
||||||
|
|
||||||
void searchCPU() const;
|
void searchCPU() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
SearchManager<T>::SearchManager(HashTable<T> &ht) {
|
SearchManager<T>::SearchManager(HashTable<T> *ht) {
|
||||||
this->hashTable = ht;
|
this->hashTable = ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,11 +27,13 @@ void SearchManager<T>::searchCPU() const {
|
|||||||
std::cin >> cpuID;
|
std::cin >> cpuID;
|
||||||
|
|
||||||
// Search for the CPU in the HashTable
|
// Search for the CPU in the HashTable
|
||||||
CPU *foundCPU = hashTable.search(cpuID);
|
CPU foundCPU;
|
||||||
|
foundCPU.setCpuId(cpuID);
|
||||||
|
int collisionCount = hashTable->search(foundCPU, foundCPU, key_to_index);
|
||||||
|
|
||||||
if (foundCPU != nullptr) {
|
if (collisionCount != -1) {
|
||||||
std::cout << "CPU found:" << std::endl;
|
std::cout << "CPU found:" << std::endl;
|
||||||
std::cout << *foundCPU << std::endl;
|
std::cout << foundCPU << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "CPU not found." << std::endl;
|
std::cout << "CPU not found." << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,12 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class UndoManager {
|
class UndoManager {
|
||||||
private:
|
private:
|
||||||
HashTable<T> hashTable;
|
HashTable<T> *hashTable;
|
||||||
BinarySearchTree<std::string> bst;
|
BinarySearchTree<std::string> *bst;
|
||||||
Stack<T> *undoStack;
|
Stack<T> *undoStack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UndoManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst);
|
UndoManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst);
|
||||||
|
|
||||||
~UndoManager();
|
~UndoManager();
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
UndoManager<T>::UndoManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst) {
|
UndoManager<T>::UndoManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst) {
|
||||||
this->hashTable = ht;
|
this->hashTable = ht;
|
||||||
this->bst = bst;
|
this->bst = bst;
|
||||||
this->undoStack = new Stack<CPU>();
|
this->undoStack = new Stack<CPU>();
|
||||||
@ -48,8 +48,8 @@ void UndoManager<T>::undoDelete() {
|
|||||||
T lastDeleted = undoStack->pop();
|
T lastDeleted = undoStack->pop();
|
||||||
|
|
||||||
// Reinsert the CPU into the HashTable and BST
|
// Reinsert the CPU into the HashTable and BST
|
||||||
hashTable.insert(lastDeleted, key_to_index);
|
hashTable->insert(lastDeleted, key_to_index);
|
||||||
bst.insert(lastDeleted.getCpuId());
|
bst->insert(lastDeleted.getCpuId());
|
||||||
|
|
||||||
std::cout << "Undo successful. CPU reinserted:" << std::endl;
|
std::cout << "Undo successful. CPU reinserted:" << std::endl;
|
||||||
std::cout << lastDeleted << std::endl;
|
std::cout << lastDeleted << std::endl;
|
||||||
|
47
fio.cpp
47
fio.cpp
@ -7,7 +7,7 @@ bool isDouble(const string &str);
|
|||||||
|
|
||||||
using std::stringstream, std::ifstream, std::getline, std::cout, std::endl, std::stoi, std::stod, std::cin;
|
using std::stringstream, std::ifstream, std::getline, std::cout, std::endl, std::stoi, std::stod, std::cin;
|
||||||
|
|
||||||
int findHashSize(const string& filename) {
|
int findHashSize(const string &filename) {
|
||||||
ifstream inputFile(filename);
|
ifstream inputFile(filename);
|
||||||
|
|
||||||
if (!inputFile) {
|
if (!inputFile) {
|
||||||
@ -25,47 +25,10 @@ int findHashSize(const string& filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
count *= 2;
|
count *= 2;
|
||||||
|
return findNextPrime(count);
|
||||||
if (count < 5) {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
while (!found) {
|
|
||||||
// Every prime number occurs only 1 number before or after a multiple of six. Every other number is divisible by either 2 or 3.
|
|
||||||
if ((count % 6) == 1) {
|
|
||||||
count += 4;
|
|
||||||
} else if ((count % 6) == 5) {
|
|
||||||
count += 2;
|
|
||||||
} else if ((count % 6) >= 2) {
|
|
||||||
count = count - (count % 6) + 5;
|
|
||||||
} else {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
for (int i = 5; i < count / 2;) {
|
|
||||||
if (count % i == 0) {
|
|
||||||
found = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 2;
|
|
||||||
|
|
||||||
if (count % i == 0) {
|
|
||||||
found = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertFile(const string& filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
|
void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
|
||||||
ifstream inputFile(filename);
|
ifstream inputFile(filename);
|
||||||
cout << "Reading data from \"" << filename << "\"" << endl;
|
cout << "Reading data from \"" << filename << "\"" << endl;
|
||||||
|
|
||||||
@ -172,7 +135,7 @@ void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
|
|||||||
hash.insert(aCPU, key_to_index);
|
hash.insert(aCPU, key_to_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInteger(const string& str) {
|
bool isInteger(const string &str) {
|
||||||
for (int i = 0; i < str.length(); i++) {
|
for (int i = 0; i < str.length(); i++) {
|
||||||
if (!(isdigit(str[i]))) {
|
if (!(isdigit(str[i]))) {
|
||||||
return false;
|
return false;
|
||||||
@ -182,7 +145,7 @@ bool isInteger(const string& str) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDouble(const string& str) {
|
bool isDouble(const string &str) {
|
||||||
int chance = 0;
|
int chance = 0;
|
||||||
|
|
||||||
for (int i = 0; i < str.length(); i++) {
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
14
main.cpp
14
main.cpp
@ -51,9 +51,9 @@ int main() {
|
|||||||
BinarySearchTree<string> cpuTree;
|
BinarySearchTree<string> cpuTree;
|
||||||
// Stack<CPU> undoStack;
|
// Stack<CPU> undoStack;
|
||||||
|
|
||||||
DisplayManager<CPU> displayManager(cpuTable, cpuTree);
|
DisplayManager<CPU> displayManager(&cpuTable, &cpuTree);
|
||||||
SearchManager<CPU> searchManager(cpuTable);
|
SearchManager<CPU> searchManager(&cpuTable);
|
||||||
UndoManager<CPU> undoManager(cpuTable, cpuTree);
|
UndoManager<CPU> undoManager(&cpuTable, &cpuTree);
|
||||||
|
|
||||||
char command = ' ';
|
char command = ' ';
|
||||||
while (command != 'Q') {
|
while (command != 'Q') {
|
||||||
@ -104,10 +104,10 @@ void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<strin
|
|||||||
undoManager.undoDelete();
|
undoManager.undoDelete();
|
||||||
break;
|
break;
|
||||||
case 'L': // List all CPUs sorted by primary key
|
case 'L': // List all CPUs sorted by primary key
|
||||||
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
displayManager.displayTree();
|
||||||
break;
|
break;
|
||||||
case 'S': // Search for a CPU by the primary key
|
case 'S': // Search for a CPU by the primary key
|
||||||
throw std::logic_error("Not yet implemented: Search for a CPU by the primary key");
|
searchManager.searchCPU();
|
||||||
break;
|
break;
|
||||||
case 'W': // Write data to a file
|
case 'W': // Write data to a file
|
||||||
handleFileOutput(cpuTable, undoManager);
|
handleFileOutput(cpuTable, undoManager);
|
||||||
@ -131,6 +131,10 @@ void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
|
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
|
||||||
|
if (hashTable.getLoadFactor() >= 75) {
|
||||||
|
cout << "Load factor is " << hashTable.getLoadFactor() << ". Rehashing...\n";
|
||||||
|
hashTable.reHash(key_to_index);
|
||||||
|
}
|
||||||
insertCPU(tree, hashTable);
|
insertCPU(tree, hashTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
utils.cpp
40
utils.cpp
@ -102,3 +102,43 @@ void printTeam() {
|
|||||||
};
|
};
|
||||||
printTable(teamWidths, teamData);
|
printTable(teamWidths, teamData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int findNextPrime(int n) {
|
||||||
|
if (n < 5) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
while (!found) {
|
||||||
|
// Every prime number occurs only 1 number before or after a multiple of six. Every other number is divisible by either 2 or 3.
|
||||||
|
if ((n % 6) == 1) {
|
||||||
|
n += 4;
|
||||||
|
} else if ((n % 6) == 5) {
|
||||||
|
n += 2;
|
||||||
|
} else if ((n % 6) >= 2) {
|
||||||
|
n = n - (n % 6) + 5;
|
||||||
|
} else {
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
for (int i = 5; i < n / 2;) {
|
||||||
|
if (n % i == 0) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
|
||||||
|
if (n % i == 0) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user