push
This commit is contained in:
parent
0f3bacbfcf
commit
6a53a30772
|
|
@ -4,9 +4,7 @@ int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
PmergeMe pm;
|
PmergeMe pm;
|
||||||
try {
|
try {
|
||||||
pm.parseInput(ac, av);
|
pm.run(ac, av);
|
||||||
pm.printVector();
|
|
||||||
pm.printDeque();
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -42,7 +42,8 @@ void PmergeMe::parseInput(int ac, char **av)
|
||||||
|
|
||||||
for (int i = 1; i < ac; i++) {
|
for (int i = 1; i < ac; i++) {
|
||||||
std::istringstream ss(av[i]);
|
std::istringstream ss(av[i]);
|
||||||
while (ss >> token) {
|
while (ss >> token)
|
||||||
|
{
|
||||||
std::istringstream iss(token);
|
std::istringstream iss(token);
|
||||||
if (!(iss >> n) || !iss.eof() || n < 0)
|
if (!(iss >> n) || !iss.eof() || n < 0)
|
||||||
throw std::runtime_error("Error");
|
throw std::runtime_error("Error");
|
||||||
|
|
@ -55,3 +56,239 @@ void PmergeMe::parseInput(int ac, char **av)
|
||||||
if (_vec.empty())
|
if (_vec.empty())
|
||||||
throw std::runtime_error("Error");
|
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;
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iomanip>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class PmergeMe
|
class PmergeMe
|
||||||
|
|
@ -23,6 +24,8 @@ class PmergeMe
|
||||||
private:
|
private:
|
||||||
std::vector<int> _vec;
|
std::vector<int> _vec;
|
||||||
std::deque<int> _deq;
|
std::deque<int> _deq;
|
||||||
|
double _vecTime;
|
||||||
|
double _deqTime;
|
||||||
|
|
||||||
void printDeque() const;
|
void printDeque() const;
|
||||||
void printVector() const;
|
void printVector() const;
|
||||||
|
|
@ -32,6 +35,8 @@ class PmergeMe
|
||||||
void sortVector();
|
void sortVector();
|
||||||
void sortDeque();
|
void sortDeque();
|
||||||
|
|
||||||
|
std::vector<int> fordJohnsonVec(std::vector<int> v);
|
||||||
|
std::deque<int> fordJohnsonDeque(std::deque<int> v);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue