Refactor PmergeMe class; implement template-based constructor and sorting methods, enhance output formatting, and update VSCode settings
This commit is contained in:
parent
e696e2a994
commit
306e63bd08
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -51,6 +51,7 @@
|
||||
"ctime": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"sstream": "cpp",
|
||||
"*.tpp": "cpp"
|
||||
"*.tpp": "cpp",
|
||||
"chrono": "cpp"
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
|
||||
template <typename Container>
|
||||
class PmergeMe
|
||||
{
|
||||
public:
|
||||
@ -16,25 +17,20 @@ public:
|
||||
PmergeMe &operator=(const PmergeMe &other);
|
||||
|
||||
void sort();
|
||||
std::string getPrintableVector() const;
|
||||
std::string getPrintableDeque() const;
|
||||
std::string getString() const;
|
||||
|
||||
private:
|
||||
std::vector<int> _data_vector;
|
||||
std::deque<int> _data_deque;
|
||||
Container _data;
|
||||
std::vector<int> _jacobstahl_numbers;
|
||||
bool less(int a, int b);
|
||||
int _comparisons;
|
||||
|
||||
bool less(int a, int b);
|
||||
bool areAllUnique() const;
|
||||
|
||||
template <typename Container>
|
||||
void insert(Container &main, Container &pend, int start_index, int right, int group_size);
|
||||
|
||||
template <typename Container>
|
||||
Container sort(Container &data, int level);
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const PmergeMe &obj);
|
||||
template <typename Container>
|
||||
std::ostream &operator<<(std::ostream &os, const PmergeMe<Container> &obj);
|
||||
|
||||
#include "PmergeMe.tpp"
|
||||
@ -1,7 +1,115 @@
|
||||
#pragma once
|
||||
|
||||
#include "PmergeMe.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
|
||||
template<typename T>
|
||||
std::string getTypeName() {
|
||||
if (std::is_same_v<T, std::vector<int>>) return "std::vector<int> ";
|
||||
if (std::is_same_v<T, std::deque<int>>) return "std::deque<int> ";
|
||||
return typeid(T).name(); // fallback to mangled name
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
Container PmergeMe::sort(Container &data, int level)
|
||||
PmergeMe<Container>::PmergeMe(const int argc, const char **argv) : _comparisons(0)
|
||||
{
|
||||
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.push_back(value);
|
||||
}
|
||||
|
||||
if (!areAllUnique())
|
||||
throw std::invalid_argument("All inputs must be unique integers");
|
||||
|
||||
if (_data.size() != static_cast<std::size_t>(argc) - 1 || _data.empty())
|
||||
throw std::invalid_argument("Invalid input detected");
|
||||
|
||||
_jacobstahl_numbers = Jacobstahl().getUpTo(_data.size());
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
PmergeMe<Container>::PmergeMe(const PmergeMe<Container> &other)
|
||||
: _data(other._data), _jacobstahl_numbers(other._jacobstahl_numbers)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
PmergeMe<Container>::~PmergeMe() {}
|
||||
|
||||
template <typename Container>
|
||||
PmergeMe<Container> &PmergeMe<Container>::operator=(const PmergeMe<Container> &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
_data = other._data;
|
||||
_jacobstahl_numbers = other._jacobstahl_numbers;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void PmergeMe<Container>::sort()
|
||||
{
|
||||
|
||||
// high resolution timing
|
||||
_comparisons = 0;
|
||||
auto time_start = std::chrono::high_resolution_clock::now();
|
||||
_data = sort(_data, 0);
|
||||
// std::cout << "Total comparisons: " << _comparisons << std::endl;
|
||||
// std::cout << (std::is_sorted(_data_vector.begin(), _data_vector.end()) ? "Sorted!!!" : "ERROR!!") << std::endl;
|
||||
auto time_end = std::chrono::high_resolution_clock::now();
|
||||
auto time_diff = std::chrono::duration_cast<std::chrono::microseconds>(time_end - time_start).count();
|
||||
std::cout << "Time to process a range of " << _data.size() << " elements with " << getTypeName<Container>() << ": " << time_diff << " us" << std::endl;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
std::string PmergeMe<Container>::getString() const
|
||||
{
|
||||
std::string result;
|
||||
for (auto it = _data.begin(); it != _data.end(); ++it)
|
||||
{
|
||||
if (it != _data.begin())
|
||||
result += ", ";
|
||||
result += std::to_string(*it);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
bool PmergeMe<Container>::less(int a, int b)
|
||||
{
|
||||
_comparisons++;
|
||||
return a < b;
|
||||
}
|
||||
template <typename Container>
|
||||
bool PmergeMe<Container>::areAllUnique() const
|
||||
{
|
||||
Container temp = _data; // Create a copy
|
||||
std::sort(temp.begin(), temp.end());
|
||||
auto it = std::unique(temp.begin(), temp.end());
|
||||
return it == temp.end();
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
Container PmergeMe<Container>::sort(Container &data, int level)
|
||||
{
|
||||
// #1 Create pairs and sort them
|
||||
if (data.size() <= 1)
|
||||
@ -60,7 +168,7 @@ Container PmergeMe::sort(Container &data, int level)
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void PmergeMe::insert(Container &main, Container &pend, int to_insert, int right, int group_size)
|
||||
void PmergeMe<Container>::insert(Container &main, Container &pend, int to_insert, int right, int group_size)
|
||||
{
|
||||
if (pend.empty() || to_insert < 0 || to_insert >= static_cast<int>(pend.size()))
|
||||
return;
|
||||
@ -82,4 +190,12 @@ void PmergeMe::insert(Container &main, Container &pend, int to_insert, int right
|
||||
|
||||
main.insert(insert_pos, pend.begin() + to_insert * group_size, pend.begin() + (to_insert + 1) * group_size);
|
||||
pend.erase(pend.begin() + to_insert * group_size, pend.begin() + (to_insert + 1) * group_size);
|
||||
}
|
||||
}
|
||||
template <typename Container>
|
||||
std::ostream &operator<<(std::ostream &os, const PmergeMe<Container> &obj)
|
||||
{
|
||||
os << obj.getString();
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -12,123 +12,15 @@
|
||||
|
||||
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;
|
||||
}
|
||||
for (std::vector<int>::const_iterator it = obj.begin(); it != obj.end(); ++it)
|
||||
{
|
||||
if (it != obj.begin())
|
||||
os << " ";
|
||||
os << *it;
|
||||
}
|
||||
|
||||
return os;
|
||||
return os;
|
||||
}
|
||||
|
||||
PmergeMe::PmergeMe(const int argc, const char **argv) : _comparisons(0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void PmergeMe::sort()
|
||||
{
|
||||
|
||||
//high resolution timing
|
||||
_comparisons = 0;
|
||||
auto time_start = std::chrono::high_resolution_clock::now();
|
||||
_data_vector = sort(_data_vector, 0);
|
||||
// std::cout << "Total comparisons: " << _comparisons << std::endl;
|
||||
// std::cout << (std::is_sorted(_data_vector.begin(), _data_vector.end()) ? "Sorted!!!" : "ERROR!!") << std::endl;
|
||||
auto time_end = std::chrono::high_resolution_clock::now();
|
||||
auto time_diff = std::chrono::duration_cast<std::chrono::microseconds>(time_end - time_start).count();
|
||||
std::cout << "Time to process a range of " << _data_vector.size() << " elements with std::vector : " << time_diff << " us" << std::endl;
|
||||
|
||||
_comparisons = 0;
|
||||
auto time_start_deque = std::chrono::high_resolution_clock::now();
|
||||
_data_deque = sort(_data_deque, 0);
|
||||
// std::cout << "Total comparisons: " << _comparisons << std::endl;
|
||||
// std::cout << (std::is_sorted(_data_deque.begin(), _data_deque.end()) ? "Sorted!!!" : "ERROR!!") << std::endl;
|
||||
auto time_end_deque = std::chrono::high_resolution_clock::now();
|
||||
auto time_diff_deque = std::chrono::duration_cast<std::chrono::microseconds>(time_end_deque - time_start_deque).count();
|
||||
std::cout << "Time to process a range of " << _data_deque.size() << " elements with std::deque : " << time_diff_deque << " us" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
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::less(int a, int b)
|
||||
{
|
||||
_comparisons++;
|
||||
return a < b;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const PmergeMe &obj)
|
||||
{
|
||||
os << "Vector: " << obj.getPrintableVector() << "\n";
|
||||
os << "Deque: " << obj.getPrintableDeque();
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
#include "Jacobstahl.hpp"
|
||||
#include "PmergeMe.hpp"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
|
||||
int main(const int argc, const char **argv)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
PmergeMe sorter(argc, argv);
|
||||
std::cout << "Before sorting:\n" << sorter << std::endl;
|
||||
PmergeMe<std::vector<int> > sorter(argc, argv);
|
||||
std::cout << "Before: " << sorter << std::endl;
|
||||
sorter.sort();
|
||||
std::cout << "After sorting:\n" << sorter << std::endl;
|
||||
PmergeMe<std::deque<int> > sorter_deque(argc, argv);
|
||||
sorter_deque.sort();
|
||||
std::cout << "After: " << sorter_deque << std::endl;
|
||||
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user