একটি সাজানোর ক্রমানুসারে সন্ধান করা
এর 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);
রিসোর্স