This commit is contained in:
root 2026-06-26 20:36:29 +00:00
parent 0f3bacbfcf
commit 6a53a30772
6 changed files with 244 additions and 4 deletions

View File

@ -4,9 +4,7 @@ int main(int ac, char **av)
{
PmergeMe pm;
try {
pm.parseInput(ac, av);
pm.printVector();
pm.printDeque();
pm.run(ac, av);
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
return 1;

BIN
ex02/PmergeMe Executable file

Binary file not shown.

View File

@ -42,7 +42,8 @@ void PmergeMe::parseInput(int ac, char **av)
for (int i = 1; i < ac; i++) {
std::istringstream ss(av[i]);
while (ss >> token) {
while (ss >> token)
{
std::istringstream iss(token);
if (!(iss >> n) || !iss.eof() || n < 0)
throw std::runtime_error("Error");
@ -55,3 +56,239 @@ void PmergeMe::parseInput(int ac, char **av)
if (_vec.empty())
throw std::runtime_error("Error");
}
void PmergeMe::run(int ac, char **av)
{
std::cout << std::fixed << std::setprecision(5);
parseInput(ac, av);
std::cout << "Before: ";
printVector();
sortVector();
sortDeque();
std::cout << "After: ";
printVector();
std::cout << "Time to process a range of " << _vec.size() << " elements with std::vector : " << _vecTime << " us" << std::endl;
std::cout << "Time to process a range of " << _deq.size() << " elements with std::deque : " << _deqTime << " us" << std::endl;
}
void PmergeMe::sortVector()
{
clock_t start = clock();
_vec = fordJohnsonVec(_vec);
clock_t end = clock();
_vecTime = (double)(end - start) * 1e6 / CLOCKS_PER_SEC;
}
std::vector<std::pair<int, int> > makePairs(std::vector<int> v)
{
std::vector<std::pair<int, int> > pairs;
for (size_t i = 0; i + 1 < v.size(); i += 2)
{
int a = v[i];
int b = v[i + 1];
if (a >= b)
pairs.push_back(std::make_pair(a, b));
else
pairs.push_back(std::make_pair(b, a));
}
return pairs;
}
std::vector<std::pair<int, int> > reorderPairs(std::vector<std::pair<int, int> > pairs, std::vector<int> winners)
{
std::vector<std::pair<int, int> > reordered;
for (size_t i = 0; i < winners.size(); i++)
{
for (size_t j = 0; j < pairs.size(); j++)
{
if (pairs[j].first == winners[i])
{
reordered.push_back(pairs[j]);
break;
}
}
}
return reordered;
}
std::vector<size_t> generateInsertionOrder(std::vector<int> pend)
{
std::vector<size_t> order;
std::vector<size_t> jacob;
jacob.push_back(0);
jacob.push_back(1);
while (jacob.back() <= pend.size())
jacob.push_back(jacob.back() + 2 * jacob[jacob.size() - 2]);
for (size_t k = 3; k < jacob.size(); k++)
{
size_t high = jacob[k] - 2;
if (high >= pend.size())
high = pend.size() - 1;
size_t low = jacob[k - 1] - 1;
for (size_t idx = high + 1; idx > low; idx--)
order.push_back(idx - 1);
}
return order;
}
std::vector<int> PmergeMe::fordJohnsonVec(std::vector<int> v)
{
if (v.size() <= 1)
return v;
std::vector<std::pair<int, int> > pairs = makePairs(v);
int straggler = 0;
bool hasStraggler = false;
if (v.size() % 2 != 0)
{
straggler = v.back();
hasStraggler = true;
}
std::vector<int> winners;
for (size_t i = 0; i < pairs.size(); i++)
winners.push_back(pairs[i].first);
winners = fordJohnsonVec(winners);
pairs = reorderPairs(pairs, winners);
std::vector<int> mainChain;
mainChain.push_back(pairs[0].second);
for (size_t i = 0; i < pairs.size(); i++)
{
mainChain.push_back(pairs[i].first);
}
std::vector<int> pend;
for (size_t i = 1; i < pairs.size(); i++)
{
pend.push_back(pairs[i].second);
}
std::vector<size_t> order = generateInsertionOrder(pend);
for (size_t i = 0; i < order.size(); i++)
{
int value = pend[order[i]];
int aiValue = pairs[order[i] + 1].first;
std::vector<int>::iterator aiPos = std::find(mainChain.begin(), mainChain.end(), aiValue);
std::vector<int>::iterator insertPos = std::upper_bound(mainChain.begin(), aiPos, value);
mainChain.insert(insertPos, value);
}
if (hasStraggler)
{
std::vector<int>::iterator insertPos = std::upper_bound(mainChain.begin(), mainChain.end(), straggler);
mainChain.insert(insertPos, straggler);
}
return mainChain;
}
void PmergeMe::sortDeque()
{
clock_t start = clock();
_deq = fordJohnsonDeque(_deq);
clock_t end = clock();
_deqTime = (double)(end - start) * 1e6 / CLOCKS_PER_SEC;
}
std::deque<std::pair<int, int> > makePairs(std::deque<int> d)
{
std::deque<std::pair<int, int> > pairs;
for (size_t i = 0; i + 1 < d.size(); i += 2)
{
int a = d[i];
int b = d[i + 1];
if (a >= b)
pairs.push_back(std::make_pair(a, b));
else
pairs.push_back(std::make_pair(b, a));
}
return pairs;
}
std::deque<std::pair<int, int> > reorderPairs(std::deque<std::pair<int, int> > pairs, std::deque<int> winners)
{
std::deque<std::pair<int, int> > reordered;
for (size_t i = 0; i < winners.size(); i++)
{
for (size_t j = 0; j < pairs.size(); j++)
{
if (pairs[j].first == winners[i])
{
reordered.push_back(pairs[j]);
break;
}
}
}
return reordered;
}
std::deque<size_t> generateInsertionOrder(std::deque<int> pend)
{
std::deque<size_t> order;
std::deque<size_t> jacob;
jacob.push_back(0);
jacob.push_back(1);
while (jacob.back() <= pend.size())
jacob.push_back(jacob.back() + 2 * jacob[jacob.size() - 2]);
for (size_t k = 3; k < jacob.size(); k++)
{
size_t high = jacob[k] - 2;
if (high >= pend.size())
high = pend.size() - 1;
size_t low = jacob[k - 1] - 1;
for (size_t idx = high + 1; idx > low; idx--)
order.push_back(idx - 1);
}
return order;
}
std::deque<int> PmergeMe::fordJohnsonDeque(std::deque<int> d)
{
if (d.size() <= 1)
return d;
std::deque<std::pair<int, int> > pairs = makePairs(d);
int straggler = 0;
bool hasStraggler = false;
if (d.size() % 2 != 0)
{
straggler = d.back();
hasStraggler = true;
}
std::deque<int> winners;
for (size_t i = 0; i < pairs.size(); i++)
winners.push_back(pairs[i].first);
winners = fordJohnsonDeque(winners);
pairs = reorderPairs(pairs, winners);
std::deque<int> mainChain;
mainChain.push_back(pairs[0].second);
for (size_t i = 0; i < pairs.size(); i++)
{
mainChain.push_back(pairs[i].first);
}
std::deque<int> pend;
for (size_t i = 1; i < pairs.size(); i++)
{
pend.push_back(pairs[i].second);
}
std::deque<size_t> order = generateInsertionOrder(pend);
for (size_t i = 0; i < order.size(); i++)
{
int value = pend[order[i]];
int aiValue = pairs[order[i] + 1].first;
std::deque<int>::iterator aiPos = std::find(mainChain.begin(), mainChain.end(), aiValue);
std::deque<int>::iterator insertPos = std::upper_bound(mainChain.begin(), aiPos, value);
mainChain.insert(insertPos, value);
}
if (hasStraggler)
{
std::deque<int>::iterator insertPos = std::upper_bound(mainChain.begin(), mainChain.end(), straggler);
mainChain.insert(insertPos, straggler);
}
return mainChain;
}

View File

@ -8,6 +8,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <iomanip>
#include <vector>
class PmergeMe
@ -23,6 +24,8 @@ class PmergeMe
private:
std::vector<int> _vec;
std::deque<int> _deq;
double _vecTime;
double _deqTime;
void printDeque() const;
void printVector() const;
@ -32,6 +35,8 @@ class PmergeMe
void sortVector();
void sortDeque();
std::vector<int> fordJohnsonVec(std::vector<int> v);
std::deque<int> fordJohnsonDeque(std::deque<int> v);
};

BIN
ex02/obj/Main.o Normal file

Binary file not shown.

BIN
ex02/obj/PmergeMe.o Normal file

Binary file not shown.