Add comparison tracking to PmergeMe sorting; enhance sorting logic and update settings

This commit is contained in:
whaffman 2025-09-03 17:52:49 +02:00
parent 25e95e3ff6
commit 1370dab089
4 changed files with 41 additions and 20 deletions

View File

@ -47,6 +47,9 @@
"stdexcept": "cpp", "stdexcept": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp" "typeinfo": "cpp",
"ctime": "cpp",
"iomanip": "cpp",
"sstream": "cpp"
} }
} }

View File

@ -25,6 +25,8 @@ 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;
bool less(int a, int b);
int _comparisons;
bool areAllUnique() const; bool areAllUnique() const;
void insertVector(std::vector<int> &main, std::vector<int> &pend, int start_index, int right, int group_size); void insertVector(std::vector<int> &main, std::vector<int> &pend, int start_index, int right, int group_size);

View File

@ -8,6 +8,7 @@
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>
#include <ostream> #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)
{ {
@ -21,7 +22,7 @@ std::ostream &operator<<(std::ostream &os, const std::vector<int> &obj)
return os; return os;
} }
PmergeMe::PmergeMe(const int argc, const char **argv) PmergeMe::PmergeMe(const int argc, const char **argv) : _comparisons(0)
{ {
for (int i = 1; argv[i] != nullptr; ++i) for (int i = 1; argv[i] != nullptr; ++i)
{ {
@ -86,7 +87,10 @@ std::ostream &PmergeMe::operator<<(std::ostream &os) const
void PmergeMe::sort() void PmergeMe::sort()
{ {
_comparisons = 0;
sortVector(0); sortVector(0);
std::cout << "Total comparisons: " << _comparisons << 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)
@ -105,7 +109,7 @@ 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 (_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);
} }
@ -117,36 +121,40 @@ void PmergeMe::sortVector(int level = 0)
// #3 Separate main and pend // #3 Separate main and pend
group_size /= 2; group_size /= 2;
main.insert(main.end(), _data_vector.begin(), _data_vector.begin() + group_size); main.insert(main.end(), _data_vector.begin(), _data_vector.begin() + group_size); // inserting b1
auto it = _data_vector.begin() + group_size; 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()) // if (it + group_size > _data_vector.end())
group_size = _data_vector.end() - it; // 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()) // if (it + group_size > _data_vector.end())
group_size = _data_vector.end() - it; // 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;
} }
pend.insert(pend.end(), left.begin(), left.end()); pend.insert(pend.end(), left.begin(), left.end());
int i = 0; int i = 0;
int sorted_in_main = 3; // TODO ??
while (!pend.empty()) while (!pend.empty())
{ {
int jacob_index = Jacobstahl().get(i + 3) - Jacobstahl().get(i + 2); 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;
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; // std::cout << "insertVector(main, pend, " << j << ", " << sorted_in_main << ", " << group_size << ")" << std::endl;
// sorted_in_main--;
} }
sorted_in_main += start_index + 1; // TODO ??
i++; i++;
} }
_data_vector = main; _data_vector = main;
@ -175,6 +183,12 @@ std::string PmergeMe::getPrintableDeque() const
return result; return result;
} }
bool PmergeMe::less(int a, int b)
{
_comparisons++;
return a < b;
}
bool PmergeMe::areAllUnique() const bool PmergeMe::areAllUnique() const
{ {
std::vector<int> temp = _data_vector; // Create a copy std::vector<int> temp = _data_vector; // Create a copy
@ -188,11 +202,13 @@ void PmergeMe::insertVector(std::vector<int> &main, std::vector<int> &pend, int
if (pend.empty() || start_index < 0 || start_index >= static_cast<int>(pend.size())) if (pend.empty() || start_index < 0 || start_index >= static_cast<int>(pend.size()))
return; 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 // 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 << "Value to insert: " << value_to_insert << std::endl;
// std::cout << main << " | " << std::setw(3) << value_to_insert << " | " << pend
// << " | start_index: " << start_index << " | right: " << right
// << " | group_size: " << group_size << (!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;
@ -201,7 +217,7 @@ void PmergeMe::insertVector(std::vector<int> &main, std::vector<int> &pend, int
{ {
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;
if (main[last_idx] < value_to_insert) if (less(main[last_idx], value_to_insert))
{ {
left = mid + 1; left = mid + 1;
} }
@ -213,7 +229,7 @@ void PmergeMe::insertVector(std::vector<int> &main, std::vector<int> &pend, int
} }
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; // 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);
} }

View File

@ -8,9 +8,9 @@ int main(const int argc, const char **argv)
try try
{ {
PmergeMe sorter(argc, argv); PmergeMe sorter(argc, argv);
std::cout << "Before sorting:\n" << sorter << std::endl; // std::cout << "Before sorting:\n" << sorter << std::endl;
sorter.sort(); sorter.sort();
std::cout << "After sorting:\n" << sorter << std::endl; // std::cout << "After sorting:\n" << sorter << std::endl;
} }
catch (const std::invalid_argument &e) catch (const std::invalid_argument &e)
{ {