Adding final assignment updates
This commit is contained in:
108
TheAlgorithmicOrganizer/BankAccount.cpp
Normal file
108
TheAlgorithmicOrganizer/BankAccount.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#include "BankAccount.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <cstdlib> // For rand()
|
||||||
|
#include <random> // For better random number generation
|
||||||
|
#include <ctime>
|
||||||
|
#include <cstring> // For memset
|
||||||
|
#include <cmath> // For floor
|
||||||
|
#include <chrono> // For time manipulation
|
||||||
|
#include <locale> // For locale settings
|
||||||
|
#include <codecvt> // For codecvt_utf8
|
||||||
|
#include <stdexcept> // For std::invalid_argument
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
TBankAccount::TBankAccount(EBankAccountType accType, std::string firstName, std::string lastName)
|
||||||
|
: accountType(accType), ownerFirstName(firstName), ownerLastName(lastName)
|
||||||
|
{
|
||||||
|
// Random genration of account number: XXXX.XX.XXXXX
|
||||||
|
accountNumber = toString(rand() % 9000 + 1000) + "." + toString(rand() % 90 + 10) + "." + toString(rand() % 90000 + 10000);
|
||||||
|
|
||||||
|
balance = 0.0f;
|
||||||
|
|
||||||
|
//Random generation of creation timestamp, date is any date and time in 2024
|
||||||
|
int month = rand() % 12 + 1;
|
||||||
|
int day = rand() % 28 + 1; // To avoid complexity of different month lengths
|
||||||
|
int hour = rand() % 24;
|
||||||
|
int minute = rand() % 60;
|
||||||
|
|
||||||
|
// Calculate creation timestamp in seconds from 2024-01-01 00:00:00
|
||||||
|
std:tm tm = {};
|
||||||
|
tm.tm_year = 2024 - 1900; // Year since 1900
|
||||||
|
tm.tm_mon = rand() % 12; // Month [0-11]
|
||||||
|
tm.tm_mday = rand() % 28 + 1; // Day of the month [1-28] to avoid month length issues
|
||||||
|
tm.tm_hour = rand() % 24; // Hour [0-23]
|
||||||
|
tm.tm_min = rand() % 60; // Minute [0-59]
|
||||||
|
tm.tm_sec = 0; // Second [0-59]
|
||||||
|
creationTimestamp = _mkgmtime(&tm); // Use _mkgmtime for UTC
|
||||||
|
|
||||||
|
if (accType == Checking || accType == Saving || accType == Pension)
|
||||||
|
balance = static_cast<double>(rand() % 1001); // 0 to 1000
|
||||||
|
else if (accType == Loan)
|
||||||
|
balance = static_cast<double>(-(rand() % 25001 + 25000)); // -50000 to -25000
|
||||||
|
else if (accType == Credit)
|
||||||
|
balance = static_cast<double>(-(rand() % 1001)); // -1000 to 0
|
||||||
|
}
|
||||||
|
|
||||||
|
TBankAccount::~TBankAccount()
|
||||||
|
{
|
||||||
|
// Destructor logic if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TBankAccount::getAccountNumber() const {
|
||||||
|
return accountNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
EBankAccountType TBankAccount::getAccountType() const {
|
||||||
|
return accountType;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t TBankAccount::getCreationTimestamp() const {
|
||||||
|
return creationTimestamp;
|
||||||
|
}
|
||||||
|
double TBankAccount::getBalance() const {
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
void TBankAccount::deposit(double aAmount) {
|
||||||
|
if (aAmount > 0) balance += aAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBankAccount::withdraw(double aAmount) {
|
||||||
|
if (aAmount > 0 && aAmount <= balance) balance -= aAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TBankAccount::getAccountTypeString() const
|
||||||
|
{
|
||||||
|
switch (accountType)
|
||||||
|
{
|
||||||
|
case Checking: return "Checking";
|
||||||
|
case Saving: return "Saving";
|
||||||
|
case Credit: return "Credit";
|
||||||
|
case Pension: return "Pension";
|
||||||
|
case Loan: return "Loan";
|
||||||
|
default: return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
std::string TBankAccount::getCreationTimeString() const
|
||||||
|
{
|
||||||
|
char buffer[26];
|
||||||
|
ctime_s(buffer, sizeof(buffer), &creationTimestamp);
|
||||||
|
std::string timeString(buffer);
|
||||||
|
if (!timeString.empty() && timeString.back() == '\n') {
|
||||||
|
timeString.pop_back(); // Remove the trailing newline character
|
||||||
|
}
|
||||||
|
return timeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBankAccount::printAccountInfo() const
|
||||||
|
{
|
||||||
|
std::cout << "Account Number: " << accountNumber << ", Type: " << getAccountTypeString()
|
||||||
|
<< ", Owner: " << ownerFirstName << " " << ownerLastName
|
||||||
|
<< ", Balance: " << balance
|
||||||
|
<< ", Created: " << getCreationTimeString()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
52
TheAlgorithmicOrganizer/BankAccount.h
Normal file
52
TheAlgorithmicOrganizer/BankAccount.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef BANKACCOUNT_H
|
||||||
|
#define BANKACCOUNT_H
|
||||||
|
|
||||||
|
#include <string> // For std::string
|
||||||
|
#include <ctime> // For time_t
|
||||||
|
#include <cstdlib> // For rand()
|
||||||
|
#include <iomanip> // For std::setfill and std::setw
|
||||||
|
#include <sstream> // For std::ostringstream
|
||||||
|
#include <iostream> // For std::cout
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function to convert value to string
|
||||||
|
template <typename T>
|
||||||
|
std::string toString(T value)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << value;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum EBankAccountType { Checking, Saving, Credit, Pension, Loan };
|
||||||
|
|
||||||
|
class TBankAccount {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string accountNumber;
|
||||||
|
EBankAccountType accountType;
|
||||||
|
time_t creationTimestamp;
|
||||||
|
double balance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string ownerFirstName;
|
||||||
|
std::string ownerLastName;
|
||||||
|
|
||||||
|
//TBankAccount() {} // Don't use default constructor
|
||||||
|
TBankAccount(EBankAccountType, std::string, std::string);
|
||||||
|
~TBankAccount();
|
||||||
|
|
||||||
|
std::string getAccountNumber() const;
|
||||||
|
std::string getCreationTimeString() const;
|
||||||
|
time_t getCreationTimestamp() const;
|
||||||
|
double getBalance() const;
|
||||||
|
void deposit(double);
|
||||||
|
void withdraw(double);
|
||||||
|
EBankAccountType getAccountType() const;
|
||||||
|
std::string getAccountTypeString() const;
|
||||||
|
void printAccountInfo() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BANKACCOUNT_H
|
||||||
130
TheAlgorithmicOrganizer/BankAccountList.cpp
Normal file
130
TheAlgorithmicOrganizer/BankAccountList.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#include "BankAccountList.h"
|
||||||
|
|
||||||
|
TLinkedList::TLinkedList(bool aOwnsData) : head(nullptr), ownsData(aOwnsData), size(0) {
|
||||||
|
head = new TLinkedListNode(nullptr); // Dummy head node
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinkedList::~TLinkedList()
|
||||||
|
{
|
||||||
|
while (head->next != nullptr)
|
||||||
|
{
|
||||||
|
TLinkedListNode* temp = head->next;
|
||||||
|
head->next = temp->next;
|
||||||
|
if (ownsData) delete temp->data; // Delete the TBankAccount object
|
||||||
|
delete temp; // Delete the node
|
||||||
|
}
|
||||||
|
delete head;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TLinkedList::getSize() const { return size; }
|
||||||
|
|
||||||
|
void TLinkedList::Add(TBankAccount* aData)
|
||||||
|
{
|
||||||
|
TLinkedListNode* newNode = new TLinkedListNode(aData);
|
||||||
|
newNode->next = head->next;
|
||||||
|
head->next = newNode;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TBankAccount* TLinkedList::Find(FCompareAccount aCompareFunc, void* aSearchKey)
|
||||||
|
{
|
||||||
|
TLinkedListNode* current = head->next;
|
||||||
|
while (current != nullptr)
|
||||||
|
{
|
||||||
|
if (aCompareFunc(current->data, aSearchKey))
|
||||||
|
{
|
||||||
|
return current->data; // Found
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return nullptr; // Not found
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinkedList* TLinkedList::Every(FCompareAccount aCompareFunc, void* aSearchKey)
|
||||||
|
{
|
||||||
|
TLinkedList* resultList = new TLinkedList(false); // New list does not own data
|
||||||
|
TLinkedListNode* current = head->next;
|
||||||
|
while (current != nullptr)
|
||||||
|
{
|
||||||
|
if (aCompareFunc(current->data, aSearchKey))
|
||||||
|
{
|
||||||
|
resultList->Add(current->data); // Add to result list
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return resultList; // Return the new list
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through all accounts, if aEveryFunc returns false for any, return that account
|
||||||
|
TBankAccount* TLinkedList::Every(FEveryAccount aEveryFunc) {
|
||||||
|
TLinkedListNode* current = head->next;
|
||||||
|
int index = 0;
|
||||||
|
while (current != nullptr)
|
||||||
|
{
|
||||||
|
if (!aEveryFunc(current->data, index++))
|
||||||
|
{
|
||||||
|
return current->data; // Return the first account that fails the test
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return nullptr; // All accounts passed the test
|
||||||
|
}
|
||||||
|
|
||||||
|
TBankAccount** TLinkedList::ToArray()
|
||||||
|
{
|
||||||
|
if (size == 0) return nullptr;
|
||||||
|
TBankAccount** array = new TBankAccount * [size];
|
||||||
|
TLinkedListNode* current = head->next;
|
||||||
|
int index = 0;
|
||||||
|
while (current != nullptr && index < size) // Ensure index < size
|
||||||
|
{
|
||||||
|
array[index++] = current->data;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::forEach(FForEachAccount aFunc)
|
||||||
|
{
|
||||||
|
TLinkedListNode* current = head->next;
|
||||||
|
int index = 0;
|
||||||
|
while (current != nullptr)
|
||||||
|
{
|
||||||
|
aFunc(current->data, index++);
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinkedListNode* TLinkedList::getHead() const { return head; }
|
||||||
|
|
||||||
|
void TLinkedList::Append(TBankAccount* account)
|
||||||
|
{
|
||||||
|
TLinkedListNode* newNode = new TLinkedListNode(account);
|
||||||
|
TLinkedListNode* current = head;
|
||||||
|
while (current->next != nullptr)
|
||||||
|
{
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
current->next = newNode;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLinkedList::Remove(TBankAccount* account)
|
||||||
|
{
|
||||||
|
TLinkedListNode* current = head;
|
||||||
|
while (current->next != nullptr)
|
||||||
|
{
|
||||||
|
if (current->next->data == account)
|
||||||
|
{
|
||||||
|
TLinkedListNode* temp = current->next;
|
||||||
|
current->next = temp->next;
|
||||||
|
if (ownsData) delete temp->data; // Delete the TBankAccount object
|
||||||
|
delete temp; // Delete the node
|
||||||
|
size--;
|
||||||
|
return; // Exit after removing
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
51
TheAlgorithmicOrganizer/BankAccountList.h
Normal file
51
TheAlgorithmicOrganizer/BankAccountList.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef BANKACCOUNTLIST_H
|
||||||
|
#define BANKACCOUNTLIST_H
|
||||||
|
#include "BankAccount.h"
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
typedef bool (*FCompareAccount)(TBankAccount* account, void* searchKey);
|
||||||
|
typedef void (*FForEachAccount)(TBankAccount* account, int index);
|
||||||
|
typedef bool (*FEveryAccount)(TBankAccount*, int);
|
||||||
|
|
||||||
|
// Node class for linked list
|
||||||
|
class TLinkedListNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TBankAccount* data;
|
||||||
|
TLinkedListNode* next;
|
||||||
|
TLinkedListNode(TBankAccount* aData) : data(aData), next(nullptr) {}
|
||||||
|
~TLinkedListNode()
|
||||||
|
{
|
||||||
|
// Destructor logic if needed
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use dummy head node for simplicity
|
||||||
|
class TLinkedList
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TLinkedListNode* head;
|
||||||
|
bool ownsData;
|
||||||
|
int size;
|
||||||
|
public:
|
||||||
|
TLinkedList(bool);
|
||||||
|
~TLinkedList();
|
||||||
|
int getSize() const;
|
||||||
|
TLinkedListNode* getHead() const;
|
||||||
|
|
||||||
|
void Add(TBankAccount*);
|
||||||
|
|
||||||
|
TBankAccount* Find(FCompareAccount, void*);
|
||||||
|
|
||||||
|
TLinkedList* Every(FCompareAccount, void*);
|
||||||
|
TBankAccount* Every(FEveryAccount aEveryFunc);
|
||||||
|
TBankAccount** ToArray();
|
||||||
|
void forEach(FForEachAccount);
|
||||||
|
|
||||||
|
void Append(TBankAccount* account);
|
||||||
|
void Remove(TBankAccount* account);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif// BANKACCOUNTLIST_H
|
||||||
@@ -1,6 +1,19 @@
|
|||||||
cmake_minimum_required(VERSION 4.0)
|
cmake_minimum_required(VERSION 4.0)
|
||||||
project(TheAlgoeithmicOrganizer)
|
project(TheAlgorithmicOrganizer)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
add_executable(TheAlgoeithmicOrganizer main.cpp)
|
add_executable(TheAlgorithmicOrganizer main.cpp
|
||||||
|
main.h
|
||||||
|
BankAccount.h
|
||||||
|
BankAccount.cpp
|
||||||
|
BankAccountList.cpp
|
||||||
|
BankAccountList.h
|
||||||
|
FileReaderUtils.cpp
|
||||||
|
FileReaderUtils.h
|
||||||
|
ReadNames.cpp
|
||||||
|
SharedLib.h
|
||||||
|
Utils.cpp
|
||||||
|
Sort.cpp
|
||||||
|
Sort.h
|
||||||
|
)
|
||||||
|
|||||||
30
TheAlgorithmicOrganizer/FileReaderUtils.cpp
Normal file
30
TheAlgorithmicOrganizer/FileReaderUtils.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include "FileReaderUtils.h"
|
||||||
|
|
||||||
|
int GetRecordCount(const std::string& aHeaderLine)
|
||||||
|
{
|
||||||
|
size_t recordPos = aHeaderLine.find("records:=");
|
||||||
|
if (recordPos == std::string::npos)
|
||||||
|
{
|
||||||
|
return 0; // No record count found
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t countStart = recordPos + 9; // Length of "records:="
|
||||||
|
|
||||||
|
// Find the end bracket ']' or a potential semicolon ';'
|
||||||
|
size_t countEnd = aHeaderLine.find_first_of("];", countStart);
|
||||||
|
if (countEnd == std::string::npos)
|
||||||
|
{
|
||||||
|
return 0; // Malformed header
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string countStr = aHeaderLine.substr(countStart, countEnd - countStart);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// stoi = string to integer
|
||||||
|
return std::stoi(countStr);
|
||||||
|
}
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
return 0; // Malformed number
|
||||||
|
}
|
||||||
|
}
|
||||||
13
TheAlgorithmicOrganizer/FileReaderUtils.h
Normal file
13
TheAlgorithmicOrganizer/FileReaderUtils.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// FileReaderUtils.h
|
||||||
|
#pragma once
|
||||||
|
#if !defined(FILEREADERUTILS_H)
|
||||||
|
#define FILEREADERUTILS_H
|
||||||
|
#include <string>
|
||||||
|
/**
|
||||||
|
* @brief [Internal] Safely parses the "records:=N" part of a header line.
|
||||||
|
* @param aHeaderLine The line, e.g., "[NODES;records:=11]"
|
||||||
|
* @return The number of records, or 0 if not found.
|
||||||
|
*/
|
||||||
|
int GetRecordCount(const std::string& aHeaderLine);
|
||||||
|
|
||||||
|
#endif // FILEREADERUTILS_H
|
||||||
55
TheAlgorithmicOrganizer/ReadNames.cpp
Normal file
55
TheAlgorithmicOrganizer/ReadNames.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include "SharedLib.h"
|
||||||
|
#include "FileReaderUtils.h"
|
||||||
|
|
||||||
|
void readNamesFromFile(const std::string& aFilename, FNameRead aOnNameRead)
|
||||||
|
{
|
||||||
|
if (aFilename.empty()) return;
|
||||||
|
|
||||||
|
std::ifstream file(aFilename);
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
std::cerr << "Error: Could not open file " << aFilename << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
int totalCount = 0;
|
||||||
|
int currentIndex = 0;
|
||||||
|
bool keepReading = true;
|
||||||
|
|
||||||
|
// --- 1. Read the header line ---
|
||||||
|
if (std::getline(file, line))
|
||||||
|
{
|
||||||
|
// Use our shared helper to get the count
|
||||||
|
totalCount = GetRecordCount(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 2. Loop through the rest of the file ---
|
||||||
|
while (keepReading && std::getline(file, line))
|
||||||
|
{
|
||||||
|
if (line.empty()) continue;
|
||||||
|
|
||||||
|
std::istringstream nameStream(line);
|
||||||
|
std::string firstName, lastName;
|
||||||
|
|
||||||
|
// Parse "FirstName LastName"
|
||||||
|
if (nameStream >> firstName >> lastName)
|
||||||
|
{
|
||||||
|
if (aOnNameRead)
|
||||||
|
{
|
||||||
|
// Call the callback with all parameters
|
||||||
|
if (!aOnNameRead(currentIndex, totalCount, firstName, lastName))
|
||||||
|
{
|
||||||
|
keepReading = false;
|
||||||
|
}
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
106
TheAlgorithmicOrganizer/SharedLib.h
Normal file
106
TheAlgorithmicOrganizer/SharedLib.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef SHARED_LIB_H
|
||||||
|
#define SHARED_LIB_H
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include "BankAccount.h"
|
||||||
|
#include "BankAccountList.h"
|
||||||
|
|
||||||
|
// Taken from exam project. Added functions, callbacks, structs and classes are at the bottom
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate type for processing a name read from a file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aIndex">The index of the name (0-based).</param>
|
||||||
|
/// <param name="aTotalCount">The total number of names.</param>
|
||||||
|
/// <param name="aFirstName">The first name read from the file.</param>
|
||||||
|
/// <param name="aLastName">The last name read from the file.</param>
|
||||||
|
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||||
|
typedef bool (*FNameRead)(
|
||||||
|
const int aIndex,
|
||||||
|
const int aTotalCount,
|
||||||
|
const std::string& aFirstName,
|
||||||
|
const std::string& aLastName
|
||||||
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use this function to read names from a specified file and process them using a callback function.
|
||||||
|
/// </summary>
|
||||||
|
/// <function>readNamesFromFile</function>
|
||||||
|
/// <description>Reads names from a specified file and invokes a callback for each name read.</description>
|
||||||
|
/// <param name="aFilename">The path to the file containing names.</param>
|
||||||
|
/// <param name="aOnNameRead">A callback function that is called for each name read. It takes two parameters: firstName and lastName. If the callback returns false, the reading process stops.</param>
|
||||||
|
/// <param name="firstName">The first name read from the file.</param>
|
||||||
|
/// <param name="lastName">The last name read from the file.</param>
|
||||||
|
/// <returns>None.</returns>
|
||||||
|
void readNamesFromFile(const std::string& aFilename, FNameRead aOnNameRead);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate type for processing a node read from the file.
|
||||||
|
/// </summary>
|
||||||
|
/// <description>Function pointer type for a callback that processes nodes read from a file.</description>
|
||||||
|
/// <param name="aIndex">The index of the node (0-based).</param>
|
||||||
|
/// <param name="aTotalCount">The total number of nodes.</param>
|
||||||
|
/// <param name="aNode">The node std::string.</param>
|
||||||
|
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||||
|
typedef bool (*FNodeRead)(const int aIndex, const int aTotalCount, const std::string& aNode);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate type for processing an edge read from the file.
|
||||||
|
/// </summary>
|
||||||
|
/// <description>Function pointer type for a callback that processes edges read from a file.</description>
|
||||||
|
/// <param name="aIndex">The index of the edge (0-based).</param>
|
||||||
|
/// <param name="aTotalCount">The total number of edges.</param>
|
||||||
|
/// <param name="aFromNode">The from node std::string.</param>
|
||||||
|
/// <param name="aToNode">The to node std::string.</param>
|
||||||
|
/// <param name="aWeight">The weight of the edge.</param>
|
||||||
|
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||||
|
typedef bool (*FEdgeRead)(const int aIndex, const int aTotalCount, const std::string& aFromNode, const std::string& aToNode, float aWeight);
|
||||||
|
|
||||||
|
/// </summary>
|
||||||
|
/// Use this function to read a graph from a specified file and process its nodes and edges using callback functions.
|
||||||
|
/// </summary>
|
||||||
|
/// <function>readGraphFromFile</function>
|
||||||
|
/// <description>
|
||||||
|
/// Reads a graph from a specified file and invokes callbacks for each node and edge read.
|
||||||
|
/// All nodes are read first, followed by edges.
|
||||||
|
/// </description>
|
||||||
|
/// <param name="aFilename">The path to the file containing the graph data.</param>
|
||||||
|
/// <param name="aOnNodeRead">A callback function that is called for each node read. It takes one parameter: the node std::string. If the callback returns false, the reading process stops.</param>
|
||||||
|
/// <param name="aOnEdgeRead">A callback function that is called for each edge read. It takes three parameters: the fromNode std::string, the toNode std::string, and the weight float. If the callback returns false, the reading process stops.</param>
|
||||||
|
void readGraphFromFile(const std::string& aFilename, FNodeRead aOnNodeRead, FEdgeRead aOnEdgeRead);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate type for processing a song read from the file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aIndex">The index of the song (0-based).</param>
|
||||||
|
/// <param name="aTotalCount">The total number of songs.</param>
|
||||||
|
/// <param name="aArtist">The artist.</param>
|
||||||
|
/// <param name="aTitle">The title.</param>
|
||||||
|
/// <param name="aYear">The release year (as a std::string).</param>
|
||||||
|
/// <param name="aGenre">The genre.</param>
|
||||||
|
/// <param name="aSource">The source.</param>
|
||||||
|
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||||
|
typedef bool (*FSongRead)(
|
||||||
|
const int aIndex,
|
||||||
|
const int aTotalCount,
|
||||||
|
const std::string& aArtist,
|
||||||
|
const std::string& aTitle,
|
||||||
|
const std::string& aYear,
|
||||||
|
const std::string& aGenre,
|
||||||
|
const std::string& aSource
|
||||||
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads song data from a file and processes them using a callback.
|
||||||
|
/// This function automatically skips the "records:=" header.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aFilename">The path to the file (e.g., "songs.txt").</param>
|
||||||
|
/// <param name="aOnSongRead">The callback function called for each song.</param>
|
||||||
|
void ReadSongsFromFile(const std::string& aFilename, FSongRead aOnSongRead);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SHARED_LIB_H
|
||||||
82
TheAlgorithmicOrganizer/Sort.cpp
Normal file
82
TheAlgorithmicOrganizer/Sort.cpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#include "Sort.h"
|
||||||
|
|
||||||
|
int CompareByLastName(const TBankAccount* a, const TBankAccount* b)
|
||||||
|
{
|
||||||
|
if (a == b)
|
||||||
|
return 0;
|
||||||
|
if (!a)
|
||||||
|
return -1;
|
||||||
|
if (!b)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (a->ownerLastName < b->ownerLastName)
|
||||||
|
return -1;
|
||||||
|
if (a->ownerLastName > b->ownerLastName)
|
||||||
|
return 1;
|
||||||
|
if (a->ownerFirstName < b->ownerFirstName)
|
||||||
|
return -1;
|
||||||
|
if (a->ownerFirstName > b->ownerFirstName)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CompareByBalanceAsc(const TBankAccount* a, const TBankAccount* b)
|
||||||
|
{
|
||||||
|
if (a == b)
|
||||||
|
return 0;
|
||||||
|
if (!a)
|
||||||
|
return -1;
|
||||||
|
if (!b)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (a->getBalance() < b->getBalance())
|
||||||
|
return -1;
|
||||||
|
if (a->getBalance() > b->getBalance())
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmpWrap(FCompareAccounts cmp, TBankAccount* a, TBankAccount* b, OperationSummary& s)
|
||||||
|
{
|
||||||
|
++s.comparisons;
|
||||||
|
return cmp(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SwapPointers(TBankAccount* a, TBankAccount* b, OperationSummary* s)
|
||||||
|
{
|
||||||
|
std::swap(a, b);
|
||||||
|
++s->swaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sort::Sort(TBankAccount **sourceArray, int count, TLinkedList *sourceList)
|
||||||
|
: m_array(sourceArray), m_count(count), m_list(sourceList){}
|
||||||
|
|
||||||
|
TBankAccount **Sort::CloneArray() const
|
||||||
|
{
|
||||||
|
if (!m_array || m_count == 0)
|
||||||
|
return nullptr;
|
||||||
|
auto** copy = new TBankAccount*[m_count];
|
||||||
|
for (int i = 0; i < m_count; i++)
|
||||||
|
copy[i] = m_array[i];
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TLinkedList* g_cloneTarget = nullptr;
|
||||||
|
|
||||||
|
static void AppendToClone(TBankAccount* acc, int)
|
||||||
|
{
|
||||||
|
if (g_cloneTarget)
|
||||||
|
g_cloneTarget->Append(acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinkedList *Sort::CloneList() const
|
||||||
|
{
|
||||||
|
if (!m_list)
|
||||||
|
return nullptr;
|
||||||
|
auto* copy = new TLinkedList(false);
|
||||||
|
m_list->forEach(AppendToClone);
|
||||||
|
g_cloneTarget = copy;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
53
TheAlgorithmicOrganizer/Sort.h
Normal file
53
TheAlgorithmicOrganizer/Sort.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "BankAccount.h"
|
||||||
|
#include "BankAccountList.h"
|
||||||
|
|
||||||
|
typedef int (*FCompareAccounts)(TBankAccount* a, TBankAccount* b);
|
||||||
|
|
||||||
|
struct OperationSummary {
|
||||||
|
long long comparisons = 0;
|
||||||
|
long long swaps = 0;
|
||||||
|
double timeSpentInMs = 0.0;
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
comparisons = 0;
|
||||||
|
swaps = 0;
|
||||||
|
timeSpentInMs = 0.0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Sort {
|
||||||
|
public:
|
||||||
|
Sort(TBankAccount** sourceArray, int count, TLinkedList* sourceList);
|
||||||
|
|
||||||
|
TBankAccount** GetArray() const
|
||||||
|
{
|
||||||
|
return m_array;
|
||||||
|
}
|
||||||
|
int GetCount() const
|
||||||
|
{
|
||||||
|
return m_count;
|
||||||
|
}
|
||||||
|
TLinkedList* GetList() const
|
||||||
|
{
|
||||||
|
return m_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
TBankAccount** CloneArray() const;
|
||||||
|
TLinkedList* CloneList() const;
|
||||||
|
|
||||||
|
TBankAccount** SelectionSortArray(FCompareAccounts cmp, OperationSummary& out);
|
||||||
|
TLinkedList* SelectionSortList(FCompareAccounts cmp, OperationSummary& out);
|
||||||
|
TBankAccount** BubbleSortArray(FCompareAccounts cmp, OperationSummary& out);
|
||||||
|
TBankAccount** QuickSortArray(FCompareAccounts cmp, OperationSummary& out);
|
||||||
|
TLinkedList* MergeSortList(FCompareAccounts cmp, OperationSummary& out);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
TBankAccount** m_array = nullptr;
|
||||||
|
int m_count = 0;
|
||||||
|
TLinkedList* m_list = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
4
TheAlgorithmicOrganizer/Utils.cpp
Normal file
4
TheAlgorithmicOrganizer/Utils.cpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#include <bits/stl_tree.h>
|
||||||
|
|
||||||
|
#include "SharedLib.h"
|
||||||
|
|
||||||
@@ -1,7 +1,26 @@
|
|||||||
#include <iostream>
|
#include "main.h"
|
||||||
|
#include "SharedLib.h"
|
||||||
|
|
||||||
|
|
||||||
|
static TLinkedList g_list(false);
|
||||||
|
static std::vector<TBankAccount*> g_array;
|
||||||
|
|
||||||
|
static bool onNameRead(const int idx, const int total, const std::string& first, const std::string& last)
|
||||||
|
{
|
||||||
|
auto* acc = new TBankAccount(EBankAccountType::Checking, first, last);
|
||||||
|
|
||||||
|
g_list.Append(acc);
|
||||||
|
g_array.push_back(acc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::cout << "Hello, World!" << std::endl;
|
readNamesFromFile("random_names.txt", onNameRead);
|
||||||
|
|
||||||
|
Sort sorter(g_array.data(), (int)g_array.size(), &g_list);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
6
TheAlgorithmicOrganizer/main.h
Normal file
6
TheAlgorithmicOrganizer/main.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
5401
TheAlgorithmicOrganizer/random_names.txt
Normal file
5401
TheAlgorithmicOrganizer/random_names.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user