halfway part 2
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
# Ignore
|
# Ignore
|
||||||
*.zip
|
*.zip
|
||||||
@@ -5,10 +5,13 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "option1.h"
|
#include "option1.h"
|
||||||
#include "SharedLib.h"
|
#include "SharedLib.h"
|
||||||
|
#include "TLinkedList.h"
|
||||||
|
#include "TPerson.h"
|
||||||
|
|
||||||
|
TLinkedList g, e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback function to process one name.
|
* @brief Callback function to process one name.
|
||||||
*/
|
|
||||||
static bool NameReadCallback(const int aIndex, const int aTotalCount, const std::string& aFirstName, const std::string& aLastName)
|
static bool NameReadCallback(const int aIndex, const int aTotalCount, const std::string& aFirstName, const std::string& aLastName)
|
||||||
{
|
{
|
||||||
std::cout << "Reading Name " << (aIndex + 1) << " of " << aTotalCount << ": "
|
std::cout << "Reading Name " << (aIndex + 1) << " of " << aTotalCount << ": "
|
||||||
@@ -18,19 +21,70 @@ static bool NameReadCallback(const int aIndex, const int aTotalCount, const std:
|
|||||||
// Return false when aIndex is 9 to stop the loop after this one.
|
// Return false when aIndex is 9 to stop the loop after this one.
|
||||||
return (aIndex < 9);
|
return (aIndex < 9);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// *Inspired* by the provided NameReadCallback given above
|
||||||
|
static bool onNameRead(const int aIndex, int aTotalCount, const std::string& aFirstName, const std::string& aLastName)
|
||||||
|
{
|
||||||
|
const ENumStatus status = (aIndex < 1500) ? EMPLOYEE : GUEST;
|
||||||
|
|
||||||
|
const TPerson p(aFirstName, aLastName, status);
|
||||||
|
|
||||||
|
|
||||||
|
if (status == EMPLOYEE)
|
||||||
|
e.Append(p);
|
||||||
|
else
|
||||||
|
g.Append(p);
|
||||||
|
|
||||||
|
std::cout << "[" <<aIndex << "] " << aLastName << ", " << aFirstName << " | status: " << (status == 1 ? "Employee" : "Guest")
|
||||||
|
<< " | cabin size: " << p.cabinSize << std::endl;
|
||||||
|
std::cout << "---------------------------------------------------------------" << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int RunApp()
|
int RunApp()
|
||||||
{
|
{
|
||||||
// Path to the names data file
|
/* Path to the names data file
|
||||||
std::string filename = "F:\\IKT203\\VisualStudio\\DATA\\random_names.txt";
|
This is MY absolute path -- change to your local path for this to read properly
|
||||||
|
something like "C:\Users\Username\FolderYouSavedTheSubmissionIn\Exam\IKT203Exam\DATA\random_names.txt"
|
||||||
|
Double slash is needed for string to pass the correct file path */
|
||||||
|
const std::string filename = "C:\\Users\\csand\\IKT203\\Exam\\IKT203Exam\\DATA\\random_names.txt";
|
||||||
|
|
||||||
std::cout << "Reading first 10 names from file: " << filename << "\n\n";
|
std::cout << "Reading names and grouping them: " << "\n" << std::endl;
|
||||||
|
|
||||||
// Call the utility function with the name callback
|
// Call the utility function with the name callback
|
||||||
readNamesFromFile(filename, NameReadCallback);
|
readNamesFromFile(filename, onNameRead);
|
||||||
|
|
||||||
std::cout << "\nFinished reading names." << std::endl;
|
std::cout << "\nFinished reading names.\n\nSorting." << std::endl;
|
||||||
|
|
||||||
|
// Merge sorting
|
||||||
|
e.Sort();
|
||||||
|
g.Sort();
|
||||||
|
|
||||||
|
// Attempt at "beautifying" the terminal output somewhat
|
||||||
|
std::cout << "\n\n\n---------------------------------------------------------------" << std::endl;
|
||||||
|
std::cout << "Employees merge sorted alphabetically" << std::endl;
|
||||||
|
std::cout << "---------------------------------------------------------------" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < e.GetSize(); i++) {
|
||||||
|
std::cout << "[" << i << "] " << e.GetAtIndex(i).lastName << ", " << e.GetAtIndex(i).firstName
|
||||||
|
<< " | status: Employee | cabin size: " << e.GetAtIndex(i).cabinSize << std::endl;
|
||||||
|
std::cout << "---------------------------------------------------------------" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n\n\n---------------------------------------------------------------" << std::endl;
|
||||||
|
std::cout << "Guests merger sorted alphabetically" << std::endl;
|
||||||
|
std::cout << "---------------------------------------------------------------" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < g.GetSize(); i++) {
|
||||||
|
std::cout << "[" << i << "] " << g.GetAtIndex(i).lastName << ", " << g.GetAtIndex(i).firstName
|
||||||
|
<< " | status: Guest | cabin size: " << g.GetAtIndex(i).cabinSize << std::endl;
|
||||||
|
std::cout << "---------------------------------------------------------------" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
# Define a library target named "SharedLib".
|
# Define a library target named "SharedLib".
|
||||||
# We use STATIC because we are using cpp and header files.
|
# We use STATIC because we are using cpp and header files.
|
||||||
add_library(SharedLib STATIC)
|
add_library(SharedLib STATIC
|
||||||
|
TPerson.cpp
|
||||||
|
TPerson.h
|
||||||
|
TLinkedList.cpp
|
||||||
|
TLinkedList.h)
|
||||||
|
|
||||||
# --- Step 2: Add Header Files to the Library ---
|
# --- Step 2: Add Header Files to the Library ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#include "FileReaderUtils.h"
|
#include "FileReaderUtils.h"
|
||||||
|
|
||||||
#include "FileReaderUtils.h"
|
|
||||||
|
|
||||||
int GetRecordCount(const std::string& aHeaderLine)
|
int GetRecordCount(const std::string& aHeaderLine)
|
||||||
{
|
{
|
||||||
size_t recordPos = aHeaderLine.find("records:=");
|
size_t recordPos = aHeaderLine.find("records:=");
|
||||||
|
|||||||
187
Exam/IKT203Exam/Portfolio/SharedLib/TLinkedList.cpp
Normal file
187
Exam/IKT203Exam/Portfolio/SharedLib/TLinkedList.cpp
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
#include "TLinkedList.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
TLinkedList::~TLinkedList()
|
||||||
|
{
|
||||||
|
const Node* cur = head;
|
||||||
|
while (cur) {
|
||||||
|
const Node* next = cur->next;
|
||||||
|
delete cur;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::Append(const TPerson& person)
|
||||||
|
{
|
||||||
|
Node* newNode = new Node(person);
|
||||||
|
if (size == 0) {
|
||||||
|
head = tail = newNode;
|
||||||
|
} else {
|
||||||
|
tail->next = newNode;
|
||||||
|
tail = newNode;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::Prepend(const TPerson& person)
|
||||||
|
{
|
||||||
|
Node* newNode = new Node(person);
|
||||||
|
if (size == 0) {
|
||||||
|
head = tail = newNode;
|
||||||
|
} else {
|
||||||
|
newNode->next = head;
|
||||||
|
head = newNode;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::InsertAtIndex(const int index, const TPerson& person)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > size) {
|
||||||
|
std::cout << "Index out of range\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
Prepend(person);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index == size) {
|
||||||
|
Append(person);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* prev = head;
|
||||||
|
for (int i = 0; i < index - 1; ++i)
|
||||||
|
prev = prev->next;
|
||||||
|
|
||||||
|
Node* newNode = new Node(person);
|
||||||
|
newNode->next = prev->next;
|
||||||
|
prev->next = newNode;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::Remove(const int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
const Node* oldHead = head;
|
||||||
|
head = head->next;
|
||||||
|
if (size == 1)
|
||||||
|
tail = nullptr;
|
||||||
|
delete oldHead;
|
||||||
|
size--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* prev = head;
|
||||||
|
for (int i = 0; i < index - 1; ++i)
|
||||||
|
prev = prev->next;
|
||||||
|
|
||||||
|
const Node* toDelete = prev->next;
|
||||||
|
prev->next = toDelete->next;
|
||||||
|
if (toDelete == tail)
|
||||||
|
tail = prev;
|
||||||
|
delete toDelete;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPerson TLinkedList::GetAtIndex(const int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= size) {
|
||||||
|
std::cout << "Index out of range\n";
|
||||||
|
// return dummy
|
||||||
|
return {"N/A", "N/A", GUEST};
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* cur = head;
|
||||||
|
for (int i = 0; i < index; ++i)
|
||||||
|
cur = cur->next;
|
||||||
|
|
||||||
|
return cur->person;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::MergeSortSplit(Node *source, Node **front, Node **back)
|
||||||
|
{
|
||||||
|
if (source == nullptr || source->next == nullptr) {
|
||||||
|
*front = source;
|
||||||
|
*back = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* slow = source;
|
||||||
|
const Node* fast = source->next;
|
||||||
|
|
||||||
|
while (fast != nullptr) {
|
||||||
|
fast = fast->next;
|
||||||
|
if (fast != nullptr) {
|
||||||
|
slow = slow->next;
|
||||||
|
fast = fast->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*front = source;
|
||||||
|
*back = slow->next;
|
||||||
|
slow->next = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinkedList::Node *TLinkedList::MergeList(Node *a, Node *b)
|
||||||
|
{
|
||||||
|
if (a == nullptr)
|
||||||
|
return b;
|
||||||
|
if (b == nullptr)
|
||||||
|
return a;
|
||||||
|
|
||||||
|
Node* result = nullptr;
|
||||||
|
|
||||||
|
if (a->person < b->person) {
|
||||||
|
result = a;
|
||||||
|
result->next = MergeList(a->next, b);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = b;
|
||||||
|
result->next = MergeList(a, b->next);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinkedList::Node *TLinkedList::MergeSort(Node *head)
|
||||||
|
{
|
||||||
|
if (head == nullptr || head->next == nullptr)
|
||||||
|
return head;
|
||||||
|
|
||||||
|
Node* front;
|
||||||
|
Node* back;
|
||||||
|
|
||||||
|
MergeSortSplit(head, &front, &back);
|
||||||
|
|
||||||
|
front = MergeSort(front);
|
||||||
|
back = MergeSort(back);
|
||||||
|
return MergeList(front, back);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::Sort()
|
||||||
|
{
|
||||||
|
this->head = MergeSort(head);
|
||||||
|
|
||||||
|
Node* cur = this->head;
|
||||||
|
tail = nullptr;
|
||||||
|
while (cur) {
|
||||||
|
if (cur->next == nullptr)
|
||||||
|
tail = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
56
Exam/IKT203Exam/Portfolio/SharedLib/TLinkedList.h
Normal file
56
Exam/IKT203Exam/Portfolio/SharedLib/TLinkedList.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef IKT203_COURSE_ASSIGNMENTS_TLINKEDLIST_H
|
||||||
|
#define IKT203_COURSE_ASSIGNMENTS_TLINKEDLIST_H
|
||||||
|
|
||||||
|
#include "TPerson.h"
|
||||||
|
|
||||||
|
class TLinkedList {
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Node {
|
||||||
|
TPerson person;
|
||||||
|
Node* next;
|
||||||
|
explicit Node(const TPerson& p) : person(p), next(nullptr) {}
|
||||||
|
|
||||||
|
void setNext(Node* n)
|
||||||
|
{
|
||||||
|
this->next = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static Node* GetNext(const Node* n)
|
||||||
|
{
|
||||||
|
return n->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static TPerson GetPerson(Node* n)
|
||||||
|
{
|
||||||
|
return n->person;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Node* head;
|
||||||
|
Node* tail;
|
||||||
|
int size;
|
||||||
|
public:
|
||||||
|
TLinkedList() : head(nullptr), tail(nullptr), size(0) {}
|
||||||
|
~TLinkedList();
|
||||||
|
|
||||||
|
void Append(const TPerson& person);
|
||||||
|
void Prepend(const TPerson& person);
|
||||||
|
void InsertAtIndex(int index, const TPerson& person);
|
||||||
|
void Remove(int index);
|
||||||
|
[[nodiscard]] TPerson GetAtIndex(int index) const;
|
||||||
|
[[nodiscard]] int GetSize() const { return size; }
|
||||||
|
static void MergeSortSplit(Node* source, Node** front, Node** back);
|
||||||
|
static Node* MergeList(Node*, Node*);
|
||||||
|
static Node* MergeSort(Node*);
|
||||||
|
void Sort();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //IKT203_COURSE_ASSIGNMENTS_TLINKEDLIST_H
|
||||||
14
Exam/IKT203Exam/Portfolio/SharedLib/TPerson.cpp
Normal file
14
Exam/IKT203Exam/Portfolio/SharedLib/TPerson.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "TPerson.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
32
Exam/IKT203Exam/Portfolio/SharedLib/TPerson.h
Normal file
32
Exam/IKT203Exam/Portfolio/SharedLib/TPerson.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef IKT203_COURSE_ASSIGNMENTS_TPERSON_H
|
||||||
|
#define IKT203_COURSE_ASSIGNMENTS_TPERSON_H
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
enum ENumStatus {
|
||||||
|
GUEST,
|
||||||
|
EMPLOYEE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TPerson {
|
||||||
|
std::string firstName;
|
||||||
|
std::string lastName;
|
||||||
|
ENumStatus status;
|
||||||
|
int cabinSize = Utils::RandomInt(1, 4);
|
||||||
|
|
||||||
|
TPerson(std::string f, std::string l, ENumStatus s) : firstName(std::move(f)), lastName(std::move(l)), status(s){}
|
||||||
|
~TPerson() = default;
|
||||||
|
|
||||||
|
bool operator<(const TPerson& other) const
|
||||||
|
{
|
||||||
|
if (lastName < other.lastName) return true;
|
||||||
|
if (lastName > other.lastName) return false;
|
||||||
|
// same last name → compare first name
|
||||||
|
return firstName < other.firstName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //IKT203_COURSE_ASSIGNMENTS_TPERSON_H
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
@@ -76,3 +77,17 @@ int Utils::RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &re
|
|||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Utils::RandomInt(const int min, const int max)
|
||||||
|
{
|
||||||
|
static bool isSeeded = false;
|
||||||
|
if (!isSeeded) {
|
||||||
|
std::srand(static_cast<unsigned>(std::time(nullptr))); //<---- not the "best" random seeding available
|
||||||
|
isSeeded = true; // but sufficient for this use case
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max <= min)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return min + rand() % (max - min + 1); // <---- Limited randomness, but again
|
||||||
|
} // sufficient for this use case
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class Utils {
|
|||||||
static int Insert(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
static int Insert(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
||||||
static void PrintList(const TDoublyLinkedList &document);
|
static void PrintList(const TDoublyLinkedList &document);
|
||||||
static int RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
static int RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
||||||
|
static int RandomInt(int, int);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user