Compare commits
10 Commits
a74b3e2aca
...
262cbe637e
Author | SHA1 | Date | |
---|---|---|---|
262cbe637e | |||
|
4882cd51fa | ||
cd2e1470ca | |||
|
4822c356f8 | ||
|
9c8c9fa65e | ||
b26f6c4501 | |||
0e1424ea3f | |||
d00fcd2d04 | |||
466c09b944 | |||
|
def78cb76f |
@ -1,3 +1,23 @@
|
|||||||
|
/* Unit 2: BST
|
||||||
|
*
|
||||||
|
* - Written in template format for flexibility
|
||||||
|
*
|
||||||
|
* - In project, BST holds primary key of CPU IDs
|
||||||
|
*
|
||||||
|
* - Sorted based off string comparison
|
||||||
|
*
|
||||||
|
* - Has insert, search, and remove functionality
|
||||||
|
*
|
||||||
|
* - Has multiple transversal functions (inorder, preorder, postorder)
|
||||||
|
*
|
||||||
|
* - Has printTree function that prints all nodes in function
|
||||||
|
*
|
||||||
|
* - In project, function pointer is used to print in indented format
|
||||||
|
*
|
||||||
|
* Written By: Tuhin Mondal
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H
|
#ifndef INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H
|
||||||
#define INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H
|
#define INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H
|
||||||
|
|
||||||
@ -20,6 +40,7 @@ public:
|
|||||||
bool search(const T& target, T& returnedItem) const;
|
bool search(const T& target, T& returnedItem) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Caller function for private _insert() method
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void BinarySearchTree<T>::insert(const T& newEntry)
|
void BinarySearchTree<T>::insert(const T& newEntry)
|
||||||
{
|
{
|
||||||
@ -28,6 +49,7 @@ void BinarySearchTree<T>::insert(const T& newEntry)
|
|||||||
this->size++;
|
this->size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inserts and sorts a new node into BST
|
||||||
template<typename T>
|
template<typename T>
|
||||||
BinaryTreeNode<T>* BinarySearchTree<T>::_insert(BinaryTreeNode<T>* nodePtr, BinaryTreeNode<T>* newNodePtr) {
|
BinaryTreeNode<T>* BinarySearchTree<T>::_insert(BinaryTreeNode<T>* nodePtr, BinaryTreeNode<T>* newNodePtr) {
|
||||||
BinaryTreeNode<T>* pWalk = nodePtr, * parent = nullptr;
|
BinaryTreeNode<T>* pWalk = nodePtr, * parent = nullptr;
|
||||||
@ -54,6 +76,7 @@ BinaryTreeNode<T>* BinarySearchTree<T>::_insert(BinaryTreeNode<T>* nodePtr, Bina
|
|||||||
return nodePtr;
|
return nodePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Caller function for private _remove() function
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool BinarySearchTree<T>::remove(const T& item) {
|
bool BinarySearchTree<T>::remove(const T& item) {
|
||||||
BinaryTreeNode<T>* removed = _remove(this->root, item);
|
BinaryTreeNode<T>* removed = _remove(this->root, item);
|
||||||
@ -64,6 +87,7 @@ bool BinarySearchTree<T>::remove(const T& item) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removes a node from BST
|
||||||
template<typename T>
|
template<typename T>
|
||||||
BinaryTreeNode<T>* BinarySearchTree<T>::_remove(BinaryTreeNode<T>* nodePtr, const T& target) {
|
BinaryTreeNode<T>* BinarySearchTree<T>::_remove(BinaryTreeNode<T>* nodePtr, const T& target) {
|
||||||
BinaryTreeNode<T>* parNode = nullptr;
|
BinaryTreeNode<T>* parNode = nullptr;
|
||||||
@ -108,6 +132,7 @@ BinaryTreeNode<T>* BinarySearchTree<T>::_remove(BinaryTreeNode<T>* nodePtr, cons
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Caller function for private _search() function
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool BinarySearchTree<T>::search(const T& target, T& returnedItem) const
|
bool BinarySearchTree<T>::search(const T& target, T& returnedItem) const
|
||||||
{
|
{
|
||||||
@ -122,6 +147,7 @@ bool BinarySearchTree<T>::search(const T& target, T& returnedItem) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Searches for a node and returns it if found.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
BinaryTreeNode<T>* BinarySearchTree<T>::_search(BinaryTreeNode<T>* nodePtr, const T& target) const
|
BinaryTreeNode<T>* BinarySearchTree<T>::_search(BinaryTreeNode<T>* nodePtr, const T& target) const
|
||||||
{
|
{
|
||||||
|
45
BinaryTree.h
45
BinaryTree.h
@ -1,3 +1,23 @@
|
|||||||
|
/* Unit 2: BST
|
||||||
|
*
|
||||||
|
* - Written in template format for flexibility
|
||||||
|
*
|
||||||
|
* - In project, BST holds primary key of CPU IDs
|
||||||
|
*
|
||||||
|
* - Sorted based off string comparison
|
||||||
|
*
|
||||||
|
* - Has insert, search, and remove functionality
|
||||||
|
*
|
||||||
|
* - Has multiple transversal functions (inorder, preorder, postorder)
|
||||||
|
*
|
||||||
|
* - Has printTree function that prints all nodes in function
|
||||||
|
*
|
||||||
|
* - In project, function pointer is used to print in indented format
|
||||||
|
*
|
||||||
|
* Written By: Tuhin Mondal
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_BINARYTREE_H
|
#ifndef INC_08_TEAM_PROJECT_BINARYTREE_H
|
||||||
#define INC_08_TEAM_PROJECT_BINARYTREE_H
|
#define INC_08_TEAM_PROJECT_BINARYTREE_H
|
||||||
|
|
||||||
@ -20,15 +40,20 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] int getSize() const { return size; };
|
[[nodiscard]] int getSize() const { return size; };
|
||||||
|
|
||||||
|
// Caller function for private destroyTree() method
|
||||||
void clear() { destroyTree(root); root = 0; size = 0; }
|
void clear() { destroyTree(root); root = 0; size = 0; }
|
||||||
|
|
||||||
|
// Caller function for private _preorder() method
|
||||||
void preOrder(void visit(const T&)) const { _preorder(visit, root); }
|
void preOrder(void visit(const T&)) const { _preorder(visit, root); }
|
||||||
|
|
||||||
|
// Caller function for private _inorder() method
|
||||||
void inOrder(std::function<void(const T&)> visit) const { _inorder(visit, root); }
|
void inOrder(std::function<void(const T&)> visit) const { _inorder(visit, root); }
|
||||||
|
|
||||||
|
// Caller function for private _postorder() method
|
||||||
void postOrder(void visit(const T&)) const { _postorder(visit, root); }
|
void postOrder(void visit(const T&)) const { _postorder(visit, root); }
|
||||||
|
|
||||||
void printIndented(void visit(const T&)) const { _printindented(visit, root, 0); }
|
// Caller function for private _printTree() method
|
||||||
|
void printTree(void visit(const T&, int)) const { _printTree(visit, root, 1); }
|
||||||
|
|
||||||
// abstract functions to be implemented by derived class
|
// abstract functions to be implemented by derived class
|
||||||
virtual void insert(const T& newData) = 0;
|
virtual void insert(const T& newData) = 0;
|
||||||
@ -46,10 +71,11 @@ private:
|
|||||||
|
|
||||||
void _postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const;
|
void _postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const;
|
||||||
|
|
||||||
void _printindented(void visit(const T&, int), BinaryTreeNode<T>* nodePtr) const;
|
void _printTree(void visit(const T&, int), BinaryTreeNode<T>* nodePtr, int level) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Recursively deletes every node in the tree
|
||||||
template<class T>
|
template<class T>
|
||||||
void BinaryTree<T>::destroyTree(BinaryTreeNode<T>* nodePtr)
|
void BinaryTree<T>::destroyTree(BinaryTreeNode<T>* nodePtr)
|
||||||
{
|
{
|
||||||
@ -61,6 +87,7 @@ void BinaryTree<T>::destroyTree(BinaryTreeNode<T>* nodePtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Traverses through tree in preorder
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void BinaryTree<T>::_preorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
void BinaryTree<T>::_preorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
||||||
{
|
{
|
||||||
@ -72,6 +99,7 @@ void BinaryTree<T>::_preorder(void visit(const T&), BinaryTreeNode<T>* nodePtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Traverses through tree in inorder
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void BinaryTree<T>::_inorder(std::function<void(const T&)> visit, BinaryTreeNode<T>* nodePtr) const
|
void BinaryTree<T>::_inorder(std::function<void(const T&)> visit, BinaryTreeNode<T>* nodePtr) const
|
||||||
{
|
{
|
||||||
@ -84,6 +112,7 @@ void BinaryTree<T>::_inorder(std::function<void(const T&)> visit, BinaryTreeNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Traverses through tree in postorder
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void BinaryTree<T>::_postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
void BinaryTree<T>::_postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
||||||
{
|
{
|
||||||
@ -95,13 +124,15 @@ void BinaryTree<T>::_postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
// Prints tree using function pointer
|
||||||
void BinaryTree<T>::_printindented(void visit(const T&, int), BinaryTreeNode<T>* nodePtr) const {
|
template<class T>
|
||||||
|
void BinaryTree<T>::_printTree(void visit(const T&, int), BinaryTreeNode<T>* nodePtr, int level) const
|
||||||
|
{
|
||||||
if (nodePtr) {
|
if (nodePtr) {
|
||||||
T item = nodePtr->getItem();
|
T item = nodePtr->getItem();
|
||||||
_printInnerNodes(visit, nodePtr->getLeftPtr());
|
visit(item, level);
|
||||||
if (nodePtr->getLeftPtr() || nodePtr->getRightPtr()) visit(item);
|
_printTree(visit, nodePtr->getRightPtr(), level + 1);
|
||||||
_printInnerNodes(visit, nodePtr->getRightPtr());
|
_printTree(visit, nodePtr->getLeftPtr(), level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,26 @@
|
|||||||
|
/* Unit 2: BST
|
||||||
|
*
|
||||||
|
* - Written in template format for flexibility
|
||||||
|
*
|
||||||
|
* - In project, BST holds primary key of CPU IDs
|
||||||
|
*
|
||||||
|
* - Sorted based off string comparison
|
||||||
|
*
|
||||||
|
* - Has insert, search, and remove functionality
|
||||||
|
*
|
||||||
|
* - Has multiple transversal functions (inorder, preorder, postorder)
|
||||||
|
*
|
||||||
|
* - Has printTree function that prints all nodes in function
|
||||||
|
*
|
||||||
|
* - In project, function pointer is used to print in indented format
|
||||||
|
*
|
||||||
|
* Written By: Tuhin Mondal
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_BINARYTREENODE_H
|
#ifndef INC_08_TEAM_PROJECT_BINARYTREENODE_H
|
||||||
#define INC_08_TEAM_PROJECT_BINARYTREENODE_H
|
#define INC_08_TEAM_PROJECT_BINARYTREENODE_H
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class BinaryTreeNode {
|
class BinaryTreeNode {
|
||||||
private:
|
private:
|
||||||
|
15
CPU.cpp
15
CPU.cpp
@ -6,11 +6,14 @@ using namespace std;
|
|||||||
|
|
||||||
void display(const CPU &cpu) {
|
void display(const CPU &cpu) {
|
||||||
|
|
||||||
|
const int minTotalWidth = max((size_t) 38, cpu.cpuId.length() + 2);
|
||||||
|
// Calculate total width, make sure architecture fits
|
||||||
|
const vector<int> widths = {18, max(minTotalWidth - 19, (int) cpu.architecture.length() + 2)};
|
||||||
|
const int totalWidth = widths[0] + widths[1];
|
||||||
// CPU ID
|
// CPU ID
|
||||||
// width is different because bold characters are counted but invisible
|
// width is different because bold characters are counted but invisible
|
||||||
string boldCenteredCpuId = centeredStr(boldStr(cpu.cpuId), 46);
|
string boldCenteredCpuId = centeredStr(boldStr(cpu.cpuId), totalWidth + 8);
|
||||||
printTableHeader({39}, {boldCenteredCpuId});
|
printTableHeader({totalWidth + 1}, {boldCenteredCpuId});
|
||||||
static const vector<int> widths = {18, 20};
|
|
||||||
|
|
||||||
// Release Year
|
// Release Year
|
||||||
cout << "| ";
|
cout << "| ";
|
||||||
@ -52,10 +55,10 @@ void display(const CPU &cpu) {
|
|||||||
printTableFooter(widths);
|
printTableFooter(widths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iDisplay(const CPU &cpu, int level) {
|
void iDisplay(const string &cpuId, int level) {
|
||||||
for (int i = 0; i < level; i++)
|
for (int i = 0; i < level; i++)
|
||||||
cout << " ";
|
cout << "..";
|
||||||
cout << cpu.cpuId << endl;
|
cout << level << ")." << cpuId << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rowDisplay(const CPU &cpu, const vector<int> &widths) {
|
void rowDisplay(const CPU &cpu, const vector<int> &widths) {
|
||||||
|
36
CPU.h
36
CPU.h
@ -1,3 +1,8 @@
|
|||||||
|
// CPU class
|
||||||
|
//
|
||||||
|
// Written by: Kevin Galvan Serrano
|
||||||
|
// Modified by: Iurii Tatishchev
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_CPU_H
|
#ifndef INC_08_TEAM_PROJECT_CPU_H
|
||||||
#define INC_08_TEAM_PROJECT_CPU_H
|
#define INC_08_TEAM_PROJECT_CPU_H
|
||||||
|
|
||||||
@ -72,19 +77,46 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display the CPU object as a table.
|
||||||
|
*
|
||||||
|
* Written by: Iurii Tatishchev
|
||||||
|
*/
|
||||||
void display(const CPU &cpu);
|
void display(const CPU &cpu);
|
||||||
|
|
||||||
void iDisplay(const CPU &cpu, int level);
|
/*
|
||||||
|
* Display the CPU object as part of an indented tree.
|
||||||
|
*
|
||||||
|
* Written by: Tuhin Mondal
|
||||||
|
*/
|
||||||
|
void iDisplay(const std::string &cpuId, int level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display the CPU object as a table row.
|
||||||
|
*
|
||||||
|
* Written by: Iurii Tatishchev
|
||||||
|
*/
|
||||||
void rowDisplay(const CPU &cpu, const std::vector<int> &widths);
|
void rowDisplay(const CPU &cpu, const std::vector<int> &widths);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Overload the << operator to display the CPU object.
|
||||||
|
*
|
||||||
|
* Written by: Iurii Tatishchev
|
||||||
|
*/
|
||||||
std::ostream &operator<<(std::ostream &os, const CPU &cpu);
|
std::ostream &operator<<(std::ostream &os, const CPU &cpu);
|
||||||
|
|
||||||
/*~*~*~*
|
/*~*~*~*
|
||||||
Hash function: takes the key and returns the index in the hash table
|
Hash function: takes the key and returns the index in the hash table.
|
||||||
|
|
||||||
|
Written by: Joshiro Lawrence
|
||||||
*~**/
|
*~**/
|
||||||
int key_to_index(const CPU &key, int size);
|
int key_to_index(const CPU &key, int size);
|
||||||
|
|
||||||
|
/*~*~*~*
|
||||||
|
Converts the CPU object to a string.
|
||||||
|
|
||||||
|
Written by: Iurii Tatishchev
|
||||||
|
*~**/
|
||||||
std::string to_string(const CPU &cpu);
|
std::string to_string(const CPU &cpu);
|
||||||
|
|
||||||
#endif // INC_08_TEAM_PROJECT_CPU_H
|
#endif // INC_08_TEAM_PROJECT_CPU_H
|
||||||
|
@ -1,3 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Name: DisplayManager
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Manage the display of CPU information and the binary search tree
|
||||||
|
Input: HashTable and BinarySearchTree objects
|
||||||
|
Output: Displayed CPU information and tree structure
|
||||||
|
Procedure: Uses the HashTable and BinarySearchTree to retrieve and display information
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: displayAll
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Display all CPUs in the database
|
||||||
|
Input: None
|
||||||
|
Output: List of all CPUs sorted by their ID
|
||||||
|
Procedure: Iterates through the HashTable and displays each CPU's information
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: displayTree
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Display the BST as an indented tree
|
||||||
|
Input: None
|
||||||
|
Output: Indented representation of the binary search tree
|
||||||
|
Procedure: Performs an inorder traversal of the BST, displaying each node with appropriate indentation
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef DISPLAY_MANAGER_H
|
#ifndef DISPLAY_MANAGER_H
|
||||||
#define DISPLAY_MANAGER_H
|
#define DISPLAY_MANAGER_H
|
||||||
|
|
||||||
@ -55,11 +85,20 @@ void DisplayManager<T>::displayTree() const {
|
|||||||
"Architecture",
|
"Architecture",
|
||||||
"Base Clock (GHz)"
|
"Base Clock (GHz)"
|
||||||
};
|
};
|
||||||
static const std::vector<int> widths = {20, 14, 12, 20, 18};
|
std::vector<int> widths = {20, 14, 12, 20, 18};
|
||||||
printTableHeader(widths, headers);
|
|
||||||
|
|
||||||
|
// Call the BST's inorder traversal method to calculate the column widths
|
||||||
|
bst->inOrder([this, &widths](const string &cpuId) {
|
||||||
|
CPU cpu;
|
||||||
|
cpu.setCpuId(cpuId);
|
||||||
|
this->hashTable->search(cpu, cpu, key_to_index);
|
||||||
|
widths[0] = max(cpu.getCpuId().length() + 2, (size_t) widths[0]);
|
||||||
|
widths[3] = max(cpu.getArchitecture().length() + 2, (size_t) widths[3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
printTableHeader(widths, headers);
|
||||||
// Call the BST's inorder traversal method to display the tree
|
// Call the BST's inorder traversal method to display the tree
|
||||||
bst->inOrder([this](const string &cpuId) {
|
bst->inOrder([this, &widths](const string &cpuId) {
|
||||||
CPU cpu;
|
CPU cpu;
|
||||||
cpu.setCpuId(cpuId);
|
cpu.setCpuId(cpuId);
|
||||||
this->hashTable->search(cpu, cpu, key_to_index);
|
this->hashTable->search(cpu, cpu, key_to_index);
|
||||||
|
26
HashNode.h
26
HashNode.h
@ -1,9 +1,13 @@
|
|||||||
|
/*
|
||||||
|
Joshiro Lawrence - Unit 3 (Hash Table)
|
||||||
|
Wrote all functions in this file.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_HASHNODE_H
|
#ifndef INC_08_TEAM_PROJECT_HASHNODE_H
|
||||||
#define INC_08_TEAM_PROJECT_HASHNODE_H
|
#define INC_08_TEAM_PROJECT_HASHNODE_H
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class HashNode
|
class HashNode {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
T item;
|
T item;
|
||||||
int occupied; // 1 -> occupied, 0 -> empty from start, -1 -> empty after removal
|
int occupied; // 1 -> occupied, 0 -> empty from start, -1 -> empty after removal
|
||||||
@ -11,31 +15,35 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
HashNode()
|
HashNode() {
|
||||||
{
|
|
||||||
occupied = 0;
|
occupied = 0;
|
||||||
numCollisions = 0;
|
numCollisions = 0;
|
||||||
}
|
}
|
||||||
HashNode(T anItem)
|
|
||||||
{
|
HashNode(T anItem) {
|
||||||
item = anItem;
|
item = anItem;
|
||||||
occupied = 1;
|
occupied = 1;
|
||||||
numCollisions = 0;
|
numCollisions = 0;
|
||||||
}
|
}
|
||||||
HashNode(T anItem, int ocp, int nCol)
|
|
||||||
{
|
HashNode(T anItem, int ocp, int nCol) {
|
||||||
item = anItem;
|
item = anItem;
|
||||||
occupied = ocp;
|
occupied = ocp;
|
||||||
numCollisions = nCol;
|
numCollisions = nCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void setItem(const T &anItem) { item = anItem; }
|
void setItem(const T &anItem) { item = anItem; }
|
||||||
|
|
||||||
void setOccupied(int ocp) { occupied = ocp; }
|
void setOccupied(int ocp) { occupied = ocp; }
|
||||||
|
|
||||||
void setNumCollisions(int nCol) { numCollisions = nCol; }
|
void setNumCollisions(int nCol) { numCollisions = nCol; }
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
T getItem() const { return item; }
|
T getItem() const { return item; }
|
||||||
|
|
||||||
int getOccupied() const { return occupied; }
|
int getOccupied() const { return occupied; }
|
||||||
|
|
||||||
int getNumCollisions() const { return numCollisions; }
|
int getNumCollisions() const { return numCollisions; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
47
HashTable.h
47
HashTable.h
@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
Joshiro Lawrence - Unit 3 (Hash Table)
|
||||||
|
Wrote all functions in this file except for _reHash, writeToFile, and the code block of insert that deals with rehashing
|
||||||
|
|
||||||
|
The purpose of the hash table in this project is to store the CPU objects. This allows for quick insertion, search, and removal into the hash table. Specifically, the hash table allows for quick searching in this program, to tell if a CPU object exists in the database already.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_HASHTABLE_H
|
#ifndef INC_08_TEAM_PROJECT_HASHTABLE_H
|
||||||
#define INC_08_TEAM_PROJECT_HASHTABLE_H
|
#define INC_08_TEAM_PROJECT_HASHTABLE_H
|
||||||
|
|
||||||
@ -24,10 +31,12 @@ private:
|
|||||||
int hashSize;
|
int hashSize;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
void _reHash(int h(const T &key, int size));
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HashTable() {
|
HashTable() {
|
||||||
count = 0;
|
count = 0;
|
||||||
hashSize = 3;
|
hashSize = 7;
|
||||||
hashAry = new HashNode<T>[hashSize];
|
hashAry = new HashNode<T>[hashSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +68,6 @@ 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 reHash(int h(const T &key, int size));
|
|
||||||
|
|
||||||
friend void writeToFile<T>(const HashTable<T> &hashTable, const string &filename, string visit(const T &));
|
friend void writeToFile<T>(const HashTable<T> &hashTable, const string &filename, string visit(const T &));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,8 +105,11 @@ int HashTable<T>::getMaxCollisions() const {
|
|||||||
*~**/
|
*~**/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool HashTable<T>::insert(const T &itemIn, int h(const T &key, int size)) {
|
bool HashTable<T>::insert(const T &itemIn, int h(const T &key, int size)) {
|
||||||
if (count == hashSize)
|
|
||||||
return false;
|
if (getLoadFactor() >= 75) {
|
||||||
|
cout << "Load factor is " << getLoadFactor() << ". Rehashing...\n";
|
||||||
|
_reHash(key_to_index);
|
||||||
|
}
|
||||||
|
|
||||||
int ind = h(itemIn, hashSize);
|
int ind = h(itemIn, hashSize);
|
||||||
for (int i = 0; i < hashSize; i++) {
|
for (int i = 0; i < hashSize; i++) {
|
||||||
@ -170,8 +180,17 @@ int HashTable<T>::search(T &itemOut, const T &key, int h(const T &key, int size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: reHash
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By:
|
||||||
|
* Purpose: Increases the size of the Hash Table's array
|
||||||
|
* Input: Hash function
|
||||||
|
* Output: N/A
|
||||||
|
* Procedure: Creates a larger array, and then traverses the old array, rehashing each item into the new one.
|
||||||
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
void HashTable<T>::reHash(int h(const T &key, int size)) {
|
void HashTable<T>::_reHash(int h(const T &key, int size)) {
|
||||||
|
|
||||||
int nHashSize = hashSize * 2;
|
int nHashSize = hashSize * 2;
|
||||||
|
|
||||||
@ -187,11 +206,11 @@ void HashTable<T>::reHash(int h(const T &key, int size)) {
|
|||||||
|
|
||||||
int nIndex = h(aT, nHashSize);
|
int nIndex = h(aT, nHashSize);
|
||||||
|
|
||||||
for (int j = 0; j < hashSize; j++) {
|
for (int j = 0; j < nHashSize; j++) {
|
||||||
if (nHashAry[nIndex].getOccupied() != 1) {
|
if (nHashAry[nIndex].getOccupied() != 1) {
|
||||||
nHashAry[nIndex].setItem(aT);
|
nHashAry[nIndex].setItem(aT);
|
||||||
nHashAry[nIndex].setOccupied(1);
|
nHashAry[nIndex].setOccupied(1);
|
||||||
nHashAry[nIndex].setNumCollisions(i);
|
nHashAry[nIndex].setNumCollisions(j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,13 +223,22 @@ void HashTable<T>::reHash(int h(const T &key, int size)) {
|
|||||||
hashSize = nHashSize;
|
hashSize = nHashSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: writeToFile
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By:
|
||||||
|
* Purpose: Outputs each item in the hash table into a file.
|
||||||
|
* Input: Name of the file, function
|
||||||
|
* Output: N/A
|
||||||
|
* Procedure: Checks if a bucket is in use, and outputs it into the file.
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void writeToFile(const HashTable<T> &hashTable, const string &filename, string visit(const T &)) {
|
void writeToFile(const HashTable<T> &hashTable, const string &filename, string visit(const T &)) {
|
||||||
ofstream outputFile(filename);
|
ofstream outputFile(filename);
|
||||||
|
|
||||||
if (!outputFile.good()) {
|
if (!outputFile.good()) {
|
||||||
cout << "Error opening the output file: \"" << filename << "\"" << endl;
|
cout << "Error opening the output file: \"" << filename << "\"" << endl;
|
||||||
exit(EXIT_FAILURE);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFile.flush();
|
outputFile.flush();
|
||||||
@ -224,6 +252,7 @@ void writeToFile(const HashTable<T> &hashTable, const string &filename, string v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cout << "Data written to file \"" << filename << "\".\n";
|
||||||
outputFile.close();
|
outputFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Name: SearchManager
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Manage the search functionality for CPUs
|
||||||
|
Input: HashTable object
|
||||||
|
Output: Search results or error messages
|
||||||
|
Procedure: Prompts user for search criteria, uses the HashTable to find matching CPUs, and displays results
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: searchCPU
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Search for a CPU by its ID
|
||||||
|
Input: CPU ID (string)
|
||||||
|
Output: CPU information if found, or a "not found" message
|
||||||
|
Procedure: Uses the HashTable's search function to find the CPU, then displays its information
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef SEARCH_MANAGER_H
|
#ifndef SEARCH_MANAGER_H
|
||||||
#define SEARCH_MANAGER_H
|
#define SEARCH_MANAGER_H
|
||||||
|
|
||||||
|
60
Stack.h
60
Stack.h
@ -1,3 +1,63 @@
|
|||||||
|
/*
|
||||||
|
Name: Stack
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Implement a generic stack data structure
|
||||||
|
Input: Template parameter T for the type of elements stored in the stack
|
||||||
|
Output: N/A
|
||||||
|
Procedure: Uses a linked list of StackNodes to store elements in a Last-In-First-Out (LIFO) order
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: push
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Add an element to the top of the stack
|
||||||
|
Input: Element of type T to be added
|
||||||
|
Output: None
|
||||||
|
Procedure: Creates a new StackNode with the input data and adds it to the top of the stack
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: pop
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Remove and return the top element from the stack
|
||||||
|
Input: None
|
||||||
|
Output: Element of type T that was at the top of the stack
|
||||||
|
Procedure: Removes the top StackNode, returns its data, and updates the stack accordingly
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: peek
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Return the top element of the stack without removing it
|
||||||
|
Input: None
|
||||||
|
Output: Element of type T that is at the top of the stack
|
||||||
|
Procedure: Returns the data of the top StackNode without modifying the stack
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: isEmpty
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Check if the stack is empty
|
||||||
|
Input: None
|
||||||
|
Output: Boolean indicating whether the stack is empty
|
||||||
|
Procedure: Returns true if the stack contains no elements, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: getCount
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Get the number of elements in the stack
|
||||||
|
Input: None
|
||||||
|
Output: Integer representing the number of elements in the stack
|
||||||
|
Procedure: Returns the count of elements currently in the stack
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_STACK_H
|
#ifndef INC_08_TEAM_PROJECT_STACK_H
|
||||||
#define INC_08_TEAM_PROJECT_STACK_H
|
#define INC_08_TEAM_PROJECT_STACK_H
|
||||||
|
|
||||||
|
10
StackNode.h
10
StackNode.h
@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
Name: StackNode
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Represent a single node in the Stack data structure
|
||||||
|
Input: Template parameter T for the type of data stored in the node
|
||||||
|
Output: N/A
|
||||||
|
Procedure: Stores an element of data and a pointer to the next StackNode in the stack
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_STACKNODE_H
|
#ifndef INC_08_TEAM_PROJECT_STACKNODE_H
|
||||||
#define INC_08_TEAM_PROJECT_STACKNODE_H
|
#define INC_08_TEAM_PROJECT_STACKNODE_H
|
||||||
|
|
||||||
|
@ -1,3 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Name: UndoManager
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Manage the undo delete functionality
|
||||||
|
Input: HashTable, BinarySearchTree, and Stack objects
|
||||||
|
Output: Messages confirming undo operations
|
||||||
|
Procedure: Uses a Stack to keep track of deleted CPUs and reinserts them when undoing a deletion
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: addToUndoStack
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Add a deleted CPU to the undo stack
|
||||||
|
Input: CPU object
|
||||||
|
Output: None
|
||||||
|
Procedure: Pushes the deleted CPU onto the undo stack
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name: undoDelete
|
||||||
|
Written By: Kevin Galvan Serrano
|
||||||
|
Modified By:
|
||||||
|
Purpose: Undo the most recent CPU deletion
|
||||||
|
Input: None
|
||||||
|
Output: Message confirming the undo operation
|
||||||
|
Procedure: Pops a CPU from the undo stack and reinserts it into the HashTable and BinarySearchTree
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef UNDO_MANAGER_H
|
#ifndef UNDO_MANAGER_H
|
||||||
#define UNDO_MANAGER_H
|
#define UNDO_MANAGER_H
|
||||||
|
|
||||||
|
42
fio.cpp
42
fio.cpp
@ -1,3 +1,10 @@
|
|||||||
|
// Unit 5: File I/O
|
||||||
|
// - Determine hash size based on the number of records in the file
|
||||||
|
// - Read data from the input file and insert them into the hash table and BST
|
||||||
|
//
|
||||||
|
// Written by: Kevin Cremin
|
||||||
|
// Modified by: Iurii Tatishchev
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "fio.h"
|
#include "fio.h"
|
||||||
|
|
||||||
@ -10,8 +17,8 @@ using namespace std;
|
|||||||
int findHashSize(const string &filename) {
|
int findHashSize(const string &filename) {
|
||||||
ifstream inputFile(filename);
|
ifstream inputFile(filename);
|
||||||
|
|
||||||
if (!inputFile) {
|
if (!inputFile.good()) {
|
||||||
cout << "Error opening the input file: \"" << filename << "\"" << endl;
|
// cout << "Error opening the input file: \"" << filename << "\"" << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// cout << "Reading data from \"" << filename << "\"" << endl;
|
// cout << "Reading data from \"" << filename << "\"" << endl;
|
||||||
@ -32,9 +39,9 @@ void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable
|
|||||||
ifstream inputFile(filename);
|
ifstream inputFile(filename);
|
||||||
// cout << "Reading data from \"" << filename << "\"" << endl;
|
// cout << "Reading data from \"" << filename << "\"" << endl;
|
||||||
|
|
||||||
if (!inputFile) {
|
if (!inputFile.good()) {
|
||||||
cout << "Error opening the input file: \"" << filename << "\"" << endl;
|
cout << "Error opening the input file: \"" << filename << "\". Skipping...\n";
|
||||||
exit(EXIT_FAILURE);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string line;
|
string line;
|
||||||
@ -47,6 +54,12 @@ void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable
|
|||||||
|
|
||||||
getline(temp, name, ';');
|
getline(temp, name, ';');
|
||||||
|
|
||||||
|
// check if the CPU is already in the hash table
|
||||||
|
CPU key(name, -1, -1, "", -1);
|
||||||
|
if (hash.search(key, key, key_to_index) != -1) {
|
||||||
|
cout << "Duplicate CPU \"" << name << "\" found in file. Skipping...\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
temp.ignore();
|
temp.ignore();
|
||||||
getline(temp, strToNum, ';');
|
getline(temp, strToNum, ';');
|
||||||
releaseYear = stoi(strToNum);
|
releaseYear = stoi(strToNum);
|
||||||
@ -71,6 +84,7 @@ void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
cout << "Data from file \"" << filename << "\" added.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -136,6 +150,15 @@ void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
|
|||||||
hash.insert(aCPU, key_to_index);
|
hash.insert(aCPU, key_to_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: isInteger
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By:
|
||||||
|
* Purpose: Determine if input is an integer
|
||||||
|
* Input: String to test
|
||||||
|
* Output: Bool of whether input was an integer
|
||||||
|
* Procedure: Checks that all characters are digits.
|
||||||
|
*/
|
||||||
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]))) {
|
||||||
@ -146,6 +169,15 @@ bool isInteger(const string &str) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: isDouble
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By:
|
||||||
|
* Purpose: Determine if input is a double
|
||||||
|
* Input: String to test
|
||||||
|
* Output: Bool of whether input was an double
|
||||||
|
* Procedure: Checks that all characters are digits and that there is at most one period.
|
||||||
|
*/
|
||||||
bool isDouble(const string &str) {
|
bool isDouble(const string &str) {
|
||||||
int chance = 0;
|
int chance = 0;
|
||||||
|
|
||||||
|
37
fio.h
37
fio.h
@ -1,8 +1,8 @@
|
|||||||
// Unit 5: File I/O
|
// Unit 5: File I/O
|
||||||
// - Determine hash size based on the number of records in the file
|
// - Determine hash size based on the number of records in the file
|
||||||
// - Read data from the input file and insert them into the hash table and BST
|
// - Read data from the input file and insert them into the hash table and BST
|
||||||
// - Save to file (in hash table sequence)
|
// - Save to file (in hash table sequence) (in HashTable.h)
|
||||||
// - Re-hashing
|
// - Re-hashing (in HashTable.h)
|
||||||
//
|
//
|
||||||
// Written by: Kevin Cremin
|
// Written by: Kevin Cremin
|
||||||
|
|
||||||
@ -18,10 +18,39 @@
|
|||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
int findHashSize(const string& filename);
|
/*
|
||||||
|
* Name: findHashSize
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By: Iurii Tatishchev
|
||||||
|
* Purpose: Find the the necessary initial size of the hash table
|
||||||
|
* Input: Name of file
|
||||||
|
* Output: Appropriate size of hash array based on how many items are in the fileName
|
||||||
|
* Procedure: Multiplies number of items in file by two, then finds next prime number
|
||||||
|
*/
|
||||||
|
int findHashSize(const string &filename);
|
||||||
|
|
||||||
void insertFile(const string& filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash);
|
/*
|
||||||
|
* Name: insertFile
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By: Iurii Tatishchev
|
||||||
|
* Purpose: Input all items in the file into the program.
|
||||||
|
* Input: Name of file, the Binary Search Tree, and the Hash Table
|
||||||
|
* Output: N/A
|
||||||
|
* Procedure: Goes through each item in the file and inputs them into the table and tree,
|
||||||
|
* verifying that there are no duplicate keys.
|
||||||
|
*/
|
||||||
|
void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: insertCPU
|
||||||
|
* Written By: Kevin Cremin
|
||||||
|
* Modified By:
|
||||||
|
* Purpose: Input an individual CPU from the user
|
||||||
|
* Input: The Binary Search Tree and the Hash Table
|
||||||
|
* Output: N/A
|
||||||
|
* Procedure: Requests information from the user, making sure that it is not a duplicate,
|
||||||
|
* and that all inputs are the correct data type.
|
||||||
|
*/
|
||||||
void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash);
|
void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash);
|
||||||
|
|
||||||
#endif //INC_08_TEAM_PROJECT_FIO_H
|
#endif //INC_08_TEAM_PROJECT_FIO_H
|
||||||
|
63
main.cpp
63
main.cpp
@ -24,6 +24,11 @@
|
|||||||
// The output file name does not have to be the same as the input file name,
|
// The output file name does not have to be the same as the input file name,
|
||||||
// but the file format must be the same so that it can be read back into the program.
|
// but the file format must be the same so that it can be read back into the program.
|
||||||
|
|
||||||
|
// Unit 1: Main
|
||||||
|
// - Menu and input processing
|
||||||
|
//
|
||||||
|
// Written by: Iurii Tatishchev
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -40,6 +45,9 @@ using namespace std;
|
|||||||
|
|
||||||
const string DEFAULT_FILE = "out.txt";
|
const string DEFAULT_FILE = "out.txt";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Takes a command character and calls the appropriate function to process the command.
|
||||||
|
*/
|
||||||
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree,
|
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree,
|
||||||
UndoManager<CPU> &undoManager, DisplayManager<CPU> &displayManager,
|
UndoManager<CPU> &undoManager, DisplayManager<CPU> &displayManager,
|
||||||
SearchManager<CPU> &searchManager);
|
SearchManager<CPU> &searchManager);
|
||||||
@ -49,11 +57,15 @@ int main() {
|
|||||||
printHelp();
|
printHelp();
|
||||||
|
|
||||||
int hashSize = findHashSize(DEFAULT_FILE);
|
int hashSize = findHashSize(DEFAULT_FILE);
|
||||||
HashTable<CPU> cpuTable = HashTable<CPU>(hashSize);
|
HashTable<CPU> cpuTable = HashTable<CPU>(hashSize == -1 ? 7 : hashSize);
|
||||||
BinarySearchTree<string> cpuTree;
|
BinarySearchTree<string> cpuTree;
|
||||||
|
|
||||||
// Read initial data from output file
|
// Read initial data from output file if it exists
|
||||||
insertFile(DEFAULT_FILE, cpuTree, cpuTable);
|
if (hashSize != -1) {
|
||||||
|
insertFile(DEFAULT_FILE, cpuTree, cpuTable);
|
||||||
|
} else {
|
||||||
|
cout << "Could not open default file \"" << DEFAULT_FILE << "\". Starting with an empty database.\n";
|
||||||
|
}
|
||||||
|
|
||||||
DisplayManager<CPU> displayManager(&cpuTable, &cpuTree);
|
DisplayManager<CPU> displayManager(&cpuTable, &cpuTree);
|
||||||
SearchManager<CPU> searchManager(&cpuTable);
|
SearchManager<CPU> searchManager(&cpuTable);
|
||||||
@ -64,7 +76,9 @@ int main() {
|
|||||||
cout << "Enter an option (H - for help): ";
|
cout << "Enter an option (H - for help): ";
|
||||||
cin >> command;
|
cin >> command;
|
||||||
command = toupper(command, std::locale());
|
command = toupper(command, std::locale());
|
||||||
// Temporary try catch block to handle unimplemented commands
|
// Temporary try catch block to handle unimplemented commands.
|
||||||
|
// Actually, this catches exceptions like stoi (integer input too large)
|
||||||
|
// so I think leaving it is a good idea.
|
||||||
try {
|
try {
|
||||||
processInput(command, cpuTable, cpuTree, undoManager, displayManager, searchManager);
|
processInput(command, cpuTable, cpuTree, undoManager, displayManager, searchManager);
|
||||||
}
|
}
|
||||||
@ -73,18 +87,31 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Quit command received
|
// Quit command received
|
||||||
writeToFile(cpuTable, DEFAULT_FILE, to_string);
|
|
||||||
cout << "Exiting program...\n";
|
cout << "Exiting program...\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input a new record into the table and tree.
|
||||||
|
*/
|
||||||
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input data from a file into the table and tree.
|
||||||
|
*/
|
||||||
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete a record from the table and tree.
|
||||||
|
* Also adds the deleted record to the undo stack.
|
||||||
|
*/
|
||||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager);
|
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write data to a file.
|
||||||
|
* Also clears the undo stack.
|
||||||
|
*/
|
||||||
void handleFileOutput(HashTable<CPU> &hashTable, UndoManager<CPU> &undoManager);
|
void handleFileOutput(HashTable<CPU> &hashTable, UndoManager<CPU> &undoManager);
|
||||||
|
|
||||||
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree,
|
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree,
|
||||||
@ -117,17 +144,18 @@ void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<strin
|
|||||||
handleFileOutput(cpuTable, undoManager);
|
handleFileOutput(cpuTable, undoManager);
|
||||||
break;
|
break;
|
||||||
case 'T': // Hashtable statistics
|
case 'T': // Hashtable statistics
|
||||||
cout << "Load factor: " << cpuTable.getLoadFactor() << std::endl;
|
cout << "Load factor: " << cpuTable.getLoadFactor() << '\n';
|
||||||
cout << "Total number of collisions: " << cpuTable.getTotalCollisions() << std::endl;
|
cout << "Total number of collisions: " << cpuTable.getTotalCollisions() << '\n';
|
||||||
cout << "Longest collision path: " << cpuTable.getMaxCollisions() << std::endl;
|
cout << "Longest collision path: " << cpuTable.getMaxCollisions() << '\n';
|
||||||
break;
|
break;
|
||||||
case 'P': // Print indented tree
|
case 'P': // Print indented tree
|
||||||
throw std::logic_error("Not yet implemented: Print indented tree");
|
cpuTree.printTree(iDisplay);
|
||||||
break;
|
break;
|
||||||
case 'Z': // Display names of team members
|
case 'Z': // Display names of team members
|
||||||
printTeam();
|
printTeam();
|
||||||
break;
|
break;
|
||||||
case 'Q': // Quit
|
case 'Q': // Quit
|
||||||
|
writeToFile(cpuTable, DEFAULT_FILE, to_string);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cout << "Invalid command. Press 'H' to view available commands.\n";
|
cout << "Invalid command. Press 'H' to view available commands.\n";
|
||||||
@ -135,10 +163,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,19 +172,19 @@ void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree)
|
|||||||
cin >> filename;
|
cin >> filename;
|
||||||
|
|
||||||
insertFile(filename, tree, hashTable);
|
insertFile(filename, tree, hashTable);
|
||||||
cout << "Data from file \"" << filename << "\" added.\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager) {
|
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager) {
|
||||||
string cpuId;
|
string cpuId;
|
||||||
cout << "Enter CPU ID to delete: ";
|
cout << "Enter CPU ID to delete: ";
|
||||||
cin >> cpuId;
|
cin.ignore();
|
||||||
|
getline(cin, cpuId);
|
||||||
|
|
||||||
CPU cpu(cpuId, 0, 0, "", 0.0);
|
CPU cpu(cpuId, 0, 0, "", 0.0);
|
||||||
CPU cpuFound;
|
CPU cpuFound;
|
||||||
while (hashTable.search(cpuFound, cpu, key_to_index) == -1) {
|
if (hashTable.search(cpuFound, cpu, key_to_index) == -1) {
|
||||||
cout << "CPU ID not found. Enter a valid CPU ID: ";
|
cout << "CPU ID \"" << cpuId << "\" not found.\n";
|
||||||
cin >> cpuId;
|
return;
|
||||||
cpu = CPU(cpuId, 0, 0, "", 0.0);
|
|
||||||
}
|
}
|
||||||
hashTable.remove(cpuFound, cpu, key_to_index);
|
hashTable.remove(cpuFound, cpu, key_to_index);
|
||||||
undoManager.addToUndoStack(cpuFound);
|
undoManager.addToUndoStack(cpuFound);
|
||||||
@ -175,5 +199,4 @@ void handleFileOutput(HashTable<CPU> &hashTable, UndoManager<CPU> &undoManager)
|
|||||||
cin >> filename;
|
cin >> filename;
|
||||||
writeToFile(hashTable, filename, to_string);
|
writeToFile(hashTable, filename, to_string);
|
||||||
undoManager.clearUndoStack();
|
undoManager.clearUndoStack();
|
||||||
cout << "Data written to file \"" << filename << "\".\n";
|
|
||||||
}
|
}
|
||||||
|
10
utils.cpp
10
utils.cpp
@ -58,16 +58,6 @@ void printTableFooter(const vector<int> &widths) {
|
|||||||
cout << "\b┘\n";
|
cout << "\b┘\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Print ascii/unicode table with given column widths and data. For example:
|
|
||||||
* ┌────────────────────────────────────────┬──────────┬────────────────────────┬────────────────┐
|
|
||||||
* | Col1 | Col2 | Col3 | Numeric Column |
|
|
||||||
* +========================================+==========+========================+================+
|
|
||||||
* | Value 1 | Value 2 | 123 | 10.0 |
|
|
||||||
* | Separate | cols | with a tab or 4 spaces | -2,027.1 |
|
|
||||||
* | This is a row with only one cell | | | |
|
|
||||||
* └────────────────────────────────────────┴──────────┴────────────────────────┴────────────────┘
|
|
||||||
*/
|
|
||||||
void printTable(const vector<int> &widths, const vector<vector<string>> &data) {
|
void printTable(const vector<int> &widths, const vector<vector<string>> &data) {
|
||||||
printTableHeader(widths, data[0]);
|
printTableHeader(widths, data[0]);
|
||||||
for (int i = 1; i < data.size(); i++) {
|
for (int i = 1; i < data.size(); i++) {
|
||||||
|
52
utils.h
52
utils.h
@ -1,3 +1,6 @@
|
|||||||
|
// Contains utility functions mostly for printing tables and formatting.
|
||||||
|
// Written by: Iurii Tatishchev
|
||||||
|
|
||||||
#ifndef INC_08_TEAM_PROJECT_UTILS_H
|
#ifndef INC_08_TEAM_PROJECT_UTILS_H
|
||||||
#define INC_08_TEAM_PROJECT_UTILS_H
|
#define INC_08_TEAM_PROJECT_UTILS_H
|
||||||
|
|
||||||
@ -6,22 +9,71 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a single row of a table, given the widths of each column and the data for the row.
|
||||||
|
*
|
||||||
|
* Example output:
|
||||||
|
* | Value 1 | Value 2 | 123 | 10.0 |
|
||||||
|
*/
|
||||||
void printRow(const vector<int> &widths, const vector<string> &row);
|
void printRow(const vector<int> &widths, const vector<string> &row);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the header of a table, given the widths of each column and the headers for each column.
|
||||||
|
* Unicode characters are used to draw the table.
|
||||||
|
*
|
||||||
|
* Example output:
|
||||||
|
* ┌────────────────────────────────────────┬──────────┬────────────────────────┬────────────────┐
|
||||||
|
* | Col1 | Col2 | Col3 | Numeric Column |
|
||||||
|
* +========================================+==========+========================+================+
|
||||||
|
*/
|
||||||
void printTableHeader(const vector<int> &widths, const vector<string> &headers);
|
void printTableHeader(const vector<int> &widths, const vector<string> &headers);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the footer of a table, given the widths of each column.
|
||||||
|
*
|
||||||
|
* Example output:
|
||||||
|
* └────────────────────────────────────────┴──────────┴────────────────────────┴────────────────┘
|
||||||
|
*/
|
||||||
void printTableFooter(const vector<int> &widths);
|
void printTableFooter(const vector<int> &widths);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print ascii/unicode table with given column widths and data. For example:
|
||||||
|
* ┌────────────────────────────────────────┬──────────┬────────────────────────┬────────────────┐
|
||||||
|
* | Col1 | Col2 | Col3 | Numeric Column |
|
||||||
|
* +========================================+==========+========================+================+
|
||||||
|
* | Value 1 | Value 2 | 123 | 10.0 |
|
||||||
|
* | Separate | cols | with a tab or 4 spaces | -2,027.1 |
|
||||||
|
* | This is a row with only one cell | | | |
|
||||||
|
* └────────────────────────────────────────┴──────────┴────────────────────────┴────────────────┘
|
||||||
|
*/
|
||||||
void printTable(const vector<int> &widths, const vector<vector<string>> &data);
|
void printTable(const vector<int> &widths, const vector<vector<string>> &data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a help table with all available commands and their descriptions.
|
||||||
|
*/
|
||||||
void printHelp();
|
void printHelp();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a table with the team members and their roles.
|
||||||
|
*/
|
||||||
void printTeam();
|
void printTeam();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the next prime number after n.
|
||||||
|
*
|
||||||
|
* Written by: Kevin Cremin
|
||||||
|
* Modified by: Iurii Tatishchev
|
||||||
|
*/
|
||||||
int findNextPrime(int n);
|
int findNextPrime(int n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add bold control characters around a string for terminal output.
|
||||||
|
*/
|
||||||
string boldStr(const string &str);
|
string boldStr(const string &str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pad a string with spaces on both sides to center it in a string of a given width.
|
||||||
|
*/
|
||||||
string centeredStr(const string &str, int width);
|
string centeredStr(const string &str, int width);
|
||||||
|
|
||||||
#endif //INC_08_TEAM_PROJECT_UTILS_H
|
#endif //INC_08_TEAM_PROJECT_UTILS_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user