정렬 순열 찾기
std::vector<T>a와의 비교가 주어지면 T이 비교를 사용하여 벡터를 정렬하는 경우 사용할 순열을 찾을 수 있기를 원합니다.
template <typename T, typename Compare>
std::vector<std::size_t> sort_permutation(
const std::vector<T>& vec,
Compare& compare)
{
std::vector<std::size_t> p(vec.size());
std::iota(p.begin(), p.end(), 0);
std::sort(p.begin(), p.end(),
[&](std::size_t i, std::size_t j){ return compare(vec[i], vec[j]); });
return p;
}
정렬 순열 적용
a std::vector<T>와 순열이 주어지면 순열 std::vector<T>에 따라 재정렬 되는 새로운 것을 만들 수 있기를 원합니다 .
template <typename T>
std::vector<T> apply_permutation(
const std::vector<T>& vec,
const std::vector<std::size_t>& p)
{
std::vector<T> sorted_vec(vec.size());
std::transform(p.begin(), p.end(), sorted_vec.begin(),
[&](std::size_t i){ return vec[i]; });
return sorted_vec;
}
물론 apply_permutation새로 정렬 된 복사본을 반환하는 대신 벡터를 변경 하도록 수정할 수 있습니다. 이 접근 방식은 여전히 선형 시간 복잡성이며 벡터의 항목 당 1 비트를 사용합니다. 이론적으로는 여전히 선형적인 공간 복잡성입니다. 그러나 실제로 sizeof(T)큰 경우 메모리 사용량이 크게 감소 할 수 있습니다. ( 자세히보기 )
template <typename T>
void apply_permutation_in_place(
std::vector<T>& vec,
const std::vector<std::size_t>& p)
{
std::vector<bool> done(vec.size());
for (std::size_t i = 0; i < vec.size(); ++i)
{
if (done[i])
{
continue;
}
done[i] = true;
std::size_t prev_j = i;
std::size_t j = p[i];
while (i != j)
{
std::swap(vec[prev_j], vec[j]);
done[j] = true;
prev_j = j;
j = p[j];
}
}
}
예
vector<MyObject> vectorA;
vector<int> vectorB;
auto p = sort_permutation(vectorA,
[](T const& a, T const& b){ });
vectorA = apply_permutation(vectorA, p);
vectorB = apply_permutation(vectorB, p);
자원