halfway part 2
This commit is contained in:
@@ -5,10 +5,13 @@
|
||||
#include <string>
|
||||
#include "option1.h"
|
||||
#include "SharedLib.h"
|
||||
#include "TLinkedList.h"
|
||||
#include "TPerson.h"
|
||||
|
||||
TLinkedList g, e;
|
||||
|
||||
/**
|
||||
* @brief Callback function to process one name.
|
||||
*/
|
||||
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 << ": "
|
||||
@@ -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 (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()
|
||||
{
|
||||
// Path to the names data file
|
||||
std::string filename = "F:\\IKT203\\VisualStudio\\DATA\\random_names.txt";
|
||||
/* Path to the names data file
|
||||
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
|
||||
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;
|
||||
}
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
# Define a library target named "SharedLib".
|
||||
# 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 ---
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "FileReaderUtils.h"
|
||||
|
||||
#include "FileReaderUtils.h"
|
||||
|
||||
int GetRecordCount(const std::string& aHeaderLine)
|
||||
{
|
||||
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 <ctime>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
@@ -76,3 +77,17 @@ int Utils::RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &re
|
||||
}
|
||||
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 void PrintList(const TDoublyLinkedList &document);
|
||||
static int RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
||||
static int RandomInt(int, int);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user