Refactor PmergeMe class; reorganize includes, improve formatting, and streamline constructor logic
off by one error in binary search
This commit is contained in:
parent
1370dab089
commit
bfbbb4acdd
@ -1,14 +1,13 @@
|
|||||||
#include "PmergeMe.hpp"
|
#include "PmergeMe.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <string>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstring>
|
#include <string>
|
||||||
#include <cmath>
|
#include <vector>
|
||||||
#include <ostream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, const std::vector<int> &obj)
|
std::ostream &operator<<(std::ostream &os, const std::vector<int> &obj)
|
||||||
{
|
{
|
||||||
@ -40,7 +39,8 @@ PmergeMe::PmergeMe(const int argc, const char **argv) : _comparisons(0)
|
|||||||
if (!areAllUnique())
|
if (!areAllUnique())
|
||||||
throw std::invalid_argument("All inputs must be unique integers");
|
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)
|
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");
|
throw std::invalid_argument("Invalid input detected");
|
||||||
|
|
||||||
_jacobstahl_numbers = Jacobstahl().getUpTo(_data_vector.size());
|
_jacobstahl_numbers = Jacobstahl().getUpTo(_data_vector.size());
|
||||||
@ -48,12 +48,9 @@ PmergeMe::PmergeMe(const int argc, const char **argv) : _comparisons(0)
|
|||||||
|
|
||||||
PmergeMe::PmergeMe(const PmergeMe &other)
|
PmergeMe::PmergeMe(const PmergeMe &other)
|
||||||
: _data_vector(other._data_vector), _data_deque(other._data_deque), _jacobstahl_numbers(other._jacobstahl_numbers)
|
: _data_vector(other._data_vector), _data_deque(other._data_deque), _jacobstahl_numbers(other._jacobstahl_numbers)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
PmergeMe::~PmergeMe()
|
PmergeMe::~PmergeMe() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PmergeMe &PmergeMe::operator=(const PmergeMe &other)
|
PmergeMe &PmergeMe::operator=(const PmergeMe &other)
|
||||||
{
|
{
|
||||||
@ -93,6 +90,7 @@ void PmergeMe::sort()
|
|||||||
std::cout << (std::is_sorted(_data_vector.begin(), _data_vector.end()) ? "Sorted!!!" : "ERROR!!") << std::endl;
|
std::cout << (std::is_sorted(_data_vector.begin(), _data_vector.end()) ? "Sorted!!!" : "ERROR!!") << std::endl;
|
||||||
std::sort(_data_deque.begin(), _data_deque.end());
|
std::sort(_data_deque.begin(), _data_deque.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PmergeMe::sortVector(int level = 0)
|
void PmergeMe::sortVector(int level = 0)
|
||||||
{
|
{
|
||||||
// #1 Create pairs and sort them
|
// #1 Create pairs and sort them
|
||||||
@ -110,7 +108,9 @@ void PmergeMe::sortVector(int level = 0)
|
|||||||
for (size_t i = 0; i < _data_vector.size(); i += group_size)
|
for (size_t i = 0; i < _data_vector.size(); i += group_size)
|
||||||
{
|
{
|
||||||
if (!less(_data_vector[i + group_size / 2 - 1], _data_vector[i + group_size - 1]))
|
if (!less(_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);
|
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())
|
if (group_size < _data_vector.size())
|
||||||
@ -125,14 +125,10 @@ void PmergeMe::sortVector(int level = 0)
|
|||||||
auto it = _data_vector.begin() + group_size; // this is a1
|
auto it = _data_vector.begin() + group_size; // this is a1
|
||||||
while (it != _data_vector.end())
|
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);
|
main.insert(main.end(), it, it + group_size);
|
||||||
it += group_size;
|
it += group_size;
|
||||||
if (it == _data_vector.end())
|
if (it == _data_vector.end())
|
||||||
break;
|
break;
|
||||||
// if (it + group_size > _data_vector.end())
|
|
||||||
// group_size = _data_vector.end() - it;
|
|
||||||
pend.insert(pend.end(), it, it + group_size);
|
pend.insert(pend.end(), it, it + group_size);
|
||||||
it += group_size;
|
it += group_size;
|
||||||
}
|
}
|
||||||
@ -142,17 +138,16 @@ void PmergeMe::sortVector(int level = 0)
|
|||||||
while (!pend.empty())
|
while (!pend.empty())
|
||||||
{
|
{
|
||||||
int sorted_in_main = std::pow(2, i + 2) - 1; // TODO ??
|
int sorted_in_main = std::pow(2, i + 2) - 1; // TODO ??
|
||||||
sorted_in_main = sorted_in_main > static_cast<int>(main.size() / group_size) ? static_cast<int>(main.size() / group_size) : sorted_in_main;
|
sorted_in_main = sorted_in_main > static_cast<int>(main.size() / group_size)
|
||||||
|
? static_cast<int>(main.size() / group_size)
|
||||||
|
: sorted_in_main;
|
||||||
|
|
||||||
int jacob_index = Jacobstahl().get(i + 3) - Jacobstahl().get(i + 2) - 1;
|
int jacob_index = Jacobstahl().get(i + 3) - Jacobstahl().get(i + 2) - 1;
|
||||||
int start_index = std::min(jacob_index, static_cast<int>(pend.size() / group_size) - 1);
|
int start_index = std::min(jacob_index, static_cast<int>(pend.size() / group_size) - 1);
|
||||||
|
|
||||||
for (int j = start_index; j >= 0; --j)
|
for (int j = start_index; j >= 0; --j)
|
||||||
{
|
{
|
||||||
|
|
||||||
insertVector(main, pend, j, sorted_in_main, group_size);
|
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--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
@ -171,6 +166,7 @@ std::string PmergeMe::getPrintableVector() const
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PmergeMe::getPrintableDeque() const
|
std::string PmergeMe::getPrintableDeque() const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
@ -204,16 +200,16 @@ void PmergeMe::insertVector(std::vector<int> &main, std::vector<int> &pend, int
|
|||||||
|
|
||||||
// Use the last element in the group for binary search
|
// Use the last element in the group for binary search
|
||||||
int value_to_insert = pend[(start_index + 1) * group_size - 1];
|
int value_to_insert = pend[(start_index + 1) * group_size - 1];
|
||||||
// std::cout << "Value to insert: " << value_to_insert << std::endl;
|
|
||||||
// std::cout << main << " | " << std::setw(3) << value_to_insert << " | " << pend
|
std::cout
|
||||||
// << " | start_index: " << start_index << " | right: " << right
|
// << main << " | " << std::setw(3) << value_to_insert << " | " << pend << " | pend_index: " << start_index
|
||||||
// << " | group_size: " << group_size << (!std::is_sorted(main.begin(), main.end()) && group_size == 1 ? "<<<" : "")
|
<< " | main: " << main.size() / group_size << " | end: " << right << " | group_size: " << group_size
|
||||||
// << std::endl;
|
<< (!std::is_sorted(main.begin(), main.end()) && group_size == 1 ? "<<<" : "") << std::endl;
|
||||||
|
|
||||||
auto insert_pos = main.begin() + right * group_size;
|
auto insert_pos = main.begin() + right * group_size;
|
||||||
int left = 0;
|
int left = 0;
|
||||||
|
|
||||||
while (left <= right)
|
while (left < right)
|
||||||
{
|
{
|
||||||
int mid = left + (right - left) / 2;
|
int mid = left + (right - left) / 2;
|
||||||
int last_idx = std::min((mid + 1) * group_size, static_cast<int>(main.size())) - 1;
|
int last_idx = std::min((mid + 1) * group_size, static_cast<int>(main.size())) - 1;
|
||||||
@ -223,13 +219,12 @@ void PmergeMe::insertVector(std::vector<int> &main, std::vector<int> &pend, int
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
right = mid - 1;
|
right = mid;
|
||||||
insert_pos = main.begin() + (mid * group_size); // Insert before the start of the found group //TODO ??
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
insert_pos = main.begin() + (left * group_size);
|
||||||
|
|
||||||
main.insert(insert_pos, pend.begin() + start_index * group_size, pend.begin() + (start_index + 1) * group_size);
|
main.insert(insert_pos, pend.begin() + start_index * group_size, pend.begin() + (start_index + 1) * group_size);
|
||||||
// std::cout << "After insertion: " << main << std::endl;
|
|
||||||
|
|
||||||
pend.erase(pend.begin() + start_index * group_size, pend.begin() + (start_index + 1) * group_size);
|
pend.erase(pend.begin() + start_index * group_size, pend.begin() + (start_index + 1) * group_size);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user