एक क्रमपरिवर्तन ढूँढना
एक std::vector<T>और एक तुलना को देखते हुए 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;
}
एक क्रमपरिवर्तन लागू करना
एक 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रूप से सदिश को बदलने के लिए संशोधित कर सकते हैं जो आप इसे एक नई छांटी गई प्रति को वापस करने के बजाय देते हैं। यह दृष्टिकोण अभी भी रैखिक समय जटिलता है और आपके वेक्टर में प्रति आइटम एक बिट का उपयोग करता है। सैद्धांतिक रूप से, यह अभी भी रैखिक अंतरिक्ष जटिलता है; लेकिन, व्यवहार में, जब 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);
साधन