Skip to content
Snippets Groups Projects
Commit b570f810 authored by Dmitri Naumov's avatar Dmitri Naumov
Browse files

Merge pull request #840 from TomFischer/FixBugInQuicksort

[BL] Quicksort: Fix miscalculated second limit.
parents 1fbcd77e 315f8e81
No related branches found
No related tags found
No related merge requests found
...@@ -30,7 +30,7 @@ void quicksort(T1* array, std::size_t beg, std::size_t end, T2* perm) ...@@ -30,7 +30,7 @@ void quicksort(T1* array, std::size_t beg, std::size_t end, T2* perm)
// Zip input arrays. // Zip input arrays.
std::vector<std::pair<T1, T2>> data; std::vector<std::pair<T1, T2>> data;
data.reserve(end-beg); data.reserve(end-beg);
std::transform(array+beg, array+(end-beg), perm+beg, std::transform(array+beg, array+end, perm+beg,
std::back_inserter(data), std::back_inserter(data),
[](T1 const& t1, T2 const& t2) [](T1 const& t1, T2 const& t2)
{ {
...@@ -72,7 +72,7 @@ void quicksort(std::vector<T1*>& array, std::size_t beg, std::size_t end, std::v ...@@ -72,7 +72,7 @@ void quicksort(std::vector<T1*>& array, std::size_t beg, std::size_t end, std::v
// Zip input arrays. // Zip input arrays.
std::vector<std::pair<T1*, T2>> data; std::vector<std::pair<T1*, T2>> data;
data.reserve(end-beg); data.reserve(end-beg);
std::transform(array.begin()+beg, array.begin()+(end-beg), perm.begin()+beg, std::transform(array.begin()+beg, array.begin()+end, perm.begin()+beg,
std::back_inserter(data), std::back_inserter(data),
[](T1* const& t1, T2 const& t2) [](T1* const& t1, T2 const& t2)
{ {
......
...@@ -14,8 +14,10 @@ ...@@ -14,8 +14,10 @@
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
#include <random>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <tuple>
#include <vector> #include <vector>
#include <gtest/gtest.h> #include <gtest/gtest.h>
...@@ -214,3 +216,50 @@ TEST_F(BaseLibQuicksort, ReportCorrectPermutationsReverseWithPointer) ...@@ -214,3 +216,50 @@ TEST_F(BaseLibQuicksort, ReportCorrectPermutationsReverseWithPointer)
}), }),
gtest_reporter, cls); gtest_reporter, cls);
} }
template <typename T, typename Gen = ac::generator<T>>
struct randomSortedPairGenerator
{
Gen source;
using result_type = std::tuple<T, T>;
result_type operator()(std::size_t)
{
auto p = std::make_tuple(source(), source());
if (std::get<0>(p) > std::get<1>(p))
std::swap(std::get<0>(p), std::get<1>(p));
return p;
}
};
TEST_F(BaseLibQuicksort, SortsRangeAsSTLSort)
{
auto quicksortSortsRangeAsSTLSort = [](std::vector<int>& xs,
std::tuple<std::size_t, std::size_t> const& range) -> bool
{
if (xs.empty())
return true;
std::vector<std::size_t> perm(xs.size());
std::iota(perm.begin(), perm.end(), 0);
BaseLib::quicksort(xs, std::get<0>(range), std::get<1>(range), perm);
return
std::is_sorted(
xs.begin() + std::get<0>(range), xs.begin() + std::get<1>(range))
&& std::is_sorted(perm.begin(), perm.begin() + std::get<0>(range))
&& std::is_sorted(perm.begin() + std::get<1>(range), perm.end());
};
ac::check<std::vector<int>, std::tuple<std::size_t, std::size_t>>(
quicksortSortsRangeAsSTLSort,
100,
ac::make_arbitrary(ac::generator<std::vector<int>>(),
randomSortedPairGenerator<std::size_t>())
.discard_if([](std::vector<int> const& xs,
std::tuple<std::size_t, std::size_t> const& range)
{
return std::get<1>(range) >= xs.size();
}),
gtest_reporter);
}
...@@ -30,8 +30,8 @@ struct randomTupleGenerator ...@@ -30,8 +30,8 @@ struct randomTupleGenerator
} }
}; };
// Generates non-negative integers from 0 to given maximum dimension DIM /// Generates non-negative integers from 0 to given maximum dimension DIM
// independent of size. /// independent of size.
template <typename T, T DIM, typename Gen = generator<T>> template <typename T, T DIM, typename Gen = generator<T>>
struct randomCoordinateIndexGenerator struct randomCoordinateIndexGenerator
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment