Refactor PmergeMe class and implement sorting logic; update CFLAGS to use C++20; add VSCode settings
This commit is contained in:
parent
d0a1b09d9a
commit
e3d2a47a5e
52
.vscode/settings.json
vendored
Normal file
52
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"numbers": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"ranges": "cpp",
|
||||||
|
"span": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
# By: whaffman <whaffman@student.codam.nl> +#+ #
|
# By: whaffman <whaffman@student.codam.nl> +#+ #
|
||||||
# +#+ #
|
# +#+ #
|
||||||
# Created: 2025/03/21 15:00:16 by whaffman #+# #+# #
|
# Created: 2025/03/21 15:00:16 by whaffman #+# #+# #
|
||||||
# Updated: 2025/03/21 15:04:44 by whaffman ######## odam.nl #
|
# Updated: 2025/09/02 11:40:20 by whaffman ######## odam.nl #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ VPATH = src
|
|||||||
SRC = $(notdir $(wildcard src/*.cpp))
|
SRC = $(notdir $(wildcard src/*.cpp))
|
||||||
OBJ = $(SRC:.cpp=.o)
|
OBJ = $(SRC:.cpp=.o)
|
||||||
CC = c++
|
CC = c++
|
||||||
CFLAGS = -Wall -Wextra -Werror -std=c++23 -MMD
|
CFLAGS = -Wall -Wextra -Werror -std=c++20 -MMD
|
||||||
|
|
||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
|
|||||||
@ -1,29 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Jacobstahl.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <ostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
template <typename Container>
|
|
||||||
class PmergeMe
|
class PmergeMe
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PmergeMe() = delete;
|
PmergeMe() = delete;
|
||||||
PmergeMe(const Container &container);
|
PmergeMe(const int argc, const char **argv);
|
||||||
PmergeMe(const PmergeMe &other);
|
PmergeMe(const PmergeMe &other);
|
||||||
~PmergeMe();
|
~PmergeMe();
|
||||||
|
|
||||||
PmergeMe &operator=(const PmergeMe &other);
|
PmergeMe &operator=(const PmergeMe &other);
|
||||||
|
std::ostream &operator<<(std::ostream &os) const;
|
||||||
|
|
||||||
void sort();
|
void sort();
|
||||||
|
void sortVector(int level);
|
||||||
|
std::string getPrintableVector() const;
|
||||||
|
std::string getPrintableDeque() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<int> _data_vector;
|
std::vector<int> _data_vector;
|
||||||
std::deque<int> _data_deque;
|
std::deque<int> _data_deque;
|
||||||
std::vector<int> _jacobstahl_numbers;
|
std::vector<int> _jacobstahl_numbers;
|
||||||
|
|
||||||
int getJacobstahlNumber(int n);
|
|
||||||
int getJacobstahlNumberRecursive(int n);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool areAllUnique() const;
|
||||||
|
void insertVector(std::vector<int> &main, std::vector<int> &pend, int start_index, int right, int group_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const PmergeMe &obj);
|
||||||
@ -0,0 +1,236 @@
|
|||||||
|
#include "PmergeMe.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const std::vector<int> &obj)
|
||||||
|
{
|
||||||
|
for (std::vector<int>::const_iterator it = obj.begin(); it != obj.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != obj.begin())
|
||||||
|
os << " ";
|
||||||
|
os << *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
PmergeMe::PmergeMe(const int argc, const char **argv)
|
||||||
|
{
|
||||||
|
for (int i = 1; argv[i] != nullptr; ++i)
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
int value = std::stoi(argv[i], &pos);
|
||||||
|
if (value < 0)
|
||||||
|
throw std::invalid_argument("All inputs must be non-negative integers");
|
||||||
|
if (pos != std::strlen(argv[i]))
|
||||||
|
throw std::invalid_argument("Invalid input: not a valid integer");
|
||||||
|
|
||||||
|
_data_vector.push_back(value);
|
||||||
|
_data_deque.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!areAllUnique())
|
||||||
|
throw std::invalid_argument("All inputs must be unique integers");
|
||||||
|
|
||||||
|
if (_data_vector.size() != static_cast<std::size_t>(argc) - 1 || _data_deque.size() != static_cast<std::size_t>(argc) - 1)
|
||||||
|
throw std::invalid_argument("Invalid input detected");
|
||||||
|
|
||||||
|
_jacobstahl_numbers = Jacobstahl().getUpTo(_data_vector.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
PmergeMe::PmergeMe(const PmergeMe &other)
|
||||||
|
: _data_vector(other._data_vector), _data_deque(other._data_deque), _jacobstahl_numbers(other._jacobstahl_numbers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PmergeMe::~PmergeMe()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PmergeMe &PmergeMe::operator=(const PmergeMe &other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
_data_vector = other._data_vector;
|
||||||
|
_data_deque = other._data_deque;
|
||||||
|
_jacobstahl_numbers = other._jacobstahl_numbers;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &PmergeMe::operator<<(std::ostream &os) const
|
||||||
|
{
|
||||||
|
os << "Vector: ";
|
||||||
|
for (std::vector<int>::const_iterator it = _data_vector.begin(); it != _data_vector.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != _data_vector.begin())
|
||||||
|
os << " ";
|
||||||
|
os << *it;
|
||||||
|
}
|
||||||
|
os << "\nDeque: ";
|
||||||
|
for (std::deque<int>::const_iterator it = _data_deque.begin(); it != _data_deque.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != _data_deque.begin())
|
||||||
|
os << " ";
|
||||||
|
os << *it;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmergeMe::sort()
|
||||||
|
{
|
||||||
|
// Implement the sorting algorithm using _data_vector and _data_deque
|
||||||
|
// This is a placeholder for the actual sorting logic
|
||||||
|
sortVector(0);
|
||||||
|
std::sort(_data_deque.begin(), _data_deque.end());
|
||||||
|
}
|
||||||
|
void PmergeMe::sortVector(int level = 0)
|
||||||
|
{
|
||||||
|
// #1 Create pairs and sort them
|
||||||
|
if (_data_vector.size() <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t group_size = std::pow(2, level + 1);
|
||||||
|
|
||||||
|
int odd = _data_vector.size() % group_size;
|
||||||
|
|
||||||
|
std::vector<int> left = std::vector<int>(_data_vector.end() - odd, _data_vector.end());
|
||||||
|
|
||||||
|
|
||||||
|
_data_vector.erase(_data_vector.end() - odd, _data_vector.end());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < _data_vector.size(); i += group_size)
|
||||||
|
{
|
||||||
|
if (_data_vector[i + group_size / 2 - 1] > _data_vector[i + group_size - 1])
|
||||||
|
std::swap_ranges(_data_vector.begin() + i, _data_vector.begin() + i + group_size / 2, _data_vector.begin() + i + group_size / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group_size < _data_vector.size())
|
||||||
|
sortVector(level + 1);
|
||||||
|
|
||||||
|
std::vector<int> main;
|
||||||
|
std::vector<int> pend;
|
||||||
|
|
||||||
|
// #3 Separate main and pend
|
||||||
|
group_size /= 2;
|
||||||
|
main.insert(main.end(), _data_vector.begin(), _data_vector.begin() + group_size);
|
||||||
|
auto it = _data_vector.begin() + group_size;
|
||||||
|
while (it != _data_vector.end())
|
||||||
|
{
|
||||||
|
if (it + group_size > _data_vector.end())
|
||||||
|
group_size = _data_vector.end() - it;
|
||||||
|
main.insert(main.end(), it, it + group_size);
|
||||||
|
it += group_size;
|
||||||
|
if (it == _data_vector.end())
|
||||||
|
break;
|
||||||
|
if (it + group_size > _data_vector.end())
|
||||||
|
group_size = _data_vector.end() - it;
|
||||||
|
pend.insert(pend.end(), it, it + group_size);
|
||||||
|
it += group_size;
|
||||||
|
}
|
||||||
|
pend.insert(pend.end(), left.begin(), left.end());
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int sorted_in_main = 2;
|
||||||
|
while (!pend.empty())
|
||||||
|
{
|
||||||
|
int jacob_index = Jacobstahl().get(i + 3) - Jacobstahl().get(i + 2);
|
||||||
|
int start_index = std::min(jacob_index, static_cast<int>(pend.size() / group_size) - 1);
|
||||||
|
|
||||||
|
for (int j = start_index; j >= 0; --j)
|
||||||
|
{
|
||||||
|
insertVector(main, pend, j, sorted_in_main, group_size);
|
||||||
|
std::cout << "insertVector(main, pend, " << j << ", " << sorted_in_main << ", " << group_size << ")" << std::endl;
|
||||||
|
}
|
||||||
|
sorted_in_main += start_index;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
_data_vector = main;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PmergeMe::getPrintableVector() const
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
for (std::vector<int>::const_iterator it = _data_vector.begin(); it != _data_vector.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != _data_vector.begin())
|
||||||
|
result += ", ";
|
||||||
|
result += std::to_string(*it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::string PmergeMe::getPrintableDeque() const
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
for (std::deque<int>::const_iterator it = _data_deque.begin(); it != _data_deque.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != _data_deque.begin())
|
||||||
|
result += ", ";
|
||||||
|
result += std::to_string(*it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PmergeMe::areAllUnique() const
|
||||||
|
{
|
||||||
|
std::vector<int> temp = _data_vector; // Create a copy
|
||||||
|
std::sort(temp.begin(), temp.end());
|
||||||
|
auto it = std::unique(temp.begin(), temp.end());
|
||||||
|
return it == temp.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmergeMe::insertVector(std::vector<int> &main, std::vector<int> &pend, int start_index, int right, int group_size)
|
||||||
|
{
|
||||||
|
if (pend.empty() || start_index < 0 || start_index >= static_cast<int>(pend.size()))
|
||||||
|
return;
|
||||||
|
// // Find the group in pend starting at start_index
|
||||||
|
// if (start_index + group_size > static_cast<int>(pend.size()))
|
||||||
|
// group_size = pend.size() - start_index;
|
||||||
|
// if (group_size <= 0)
|
||||||
|
// return;
|
||||||
|
std::cout << main << " | " << pend << " | start_index: " << start_index << " | right: " << right << " | group_size: " << group_size << std::endl;
|
||||||
|
|
||||||
|
// Use the last element in the group for binary search
|
||||||
|
int value_to_insert = pend[(start_index + 1) * group_size - 1];
|
||||||
|
|
||||||
|
// Binary search in main for insertion position
|
||||||
|
// Binary search comparing only the last values of each group in main
|
||||||
|
auto insert_pos = main.begin() + right;
|
||||||
|
int left = 0;
|
||||||
|
// right = (main.size() + group_size - 1) / group_size - 1; // number of groups - 1
|
||||||
|
|
||||||
|
while (left <= right)
|
||||||
|
{
|
||||||
|
int mid = left + (right - left) / 2;
|
||||||
|
int last_idx = std::min((mid + 1) * group_size, static_cast<int>(main.size())) - 1;
|
||||||
|
if (main[last_idx] < value_to_insert)
|
||||||
|
{
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
right = mid - 1;
|
||||||
|
insert_pos = main.begin() + last_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the whole group before insert_pos
|
||||||
|
main.insert(insert_pos, pend.begin() + start_index * group_size, pend.begin() + (start_index + 1) * group_size);
|
||||||
|
std::cout << "After insertion: " << main << std::endl;
|
||||||
|
// Erase the group from pend
|
||||||
|
pend.erase(pend.begin() + start_index * group_size, pend.begin() + (start_index + 1) * group_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const PmergeMe &obj)
|
||||||
|
{
|
||||||
|
os << "Vector: " << obj.getPrintableVector() << "\n";
|
||||||
|
os << "Deque: " << obj.getPrintableDeque();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
@ -1,27 +1,22 @@
|
|||||||
#include "Jacobstahl.hpp"
|
#include "Jacobstahl.hpp"
|
||||||
|
#include "PmergeMe.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
int main()
|
int main(const int argc, const char **argv)
|
||||||
{
|
{
|
||||||
Jacobstahl jacobstahl;
|
|
||||||
|
|
||||||
std::cout << "First 10 Jacobstahl numbers:" << std::endl;
|
try
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
{
|
{
|
||||||
std::cout << "Jacobstahl(" << i << ") = " << jacobstahl.get(i) << std::endl;
|
PmergeMe sorter(argc, argv);
|
||||||
|
std::cout << "Before sorting:\n" << sorter << std::endl;
|
||||||
|
sorter.sort();
|
||||||
|
std::cout << "After sorting:\n" << sorter << std::endl;
|
||||||
}
|
}
|
||||||
|
catch (const std::invalid_argument &e)
|
||||||
|
|
||||||
std::vector<int> jacobstahl_numbers = jacobstahl.getUpTo(100);
|
|
||||||
std::cout << "Jacobstahl numbers up to 100:" << std::endl;
|
|
||||||
for (int num : jacobstahl_numbers)
|
|
||||||
{
|
{
|
||||||
std::cout << num << " ";
|
std::cerr << "Error: " << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << "Jacobstahl number after 100: " << jacobstahl.getAfter(100) << std::endl;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user