দুটি পরিসরের মধ্যে অবতরণ ক্রমে একটি ভেক্টর বাছাই করা


14

বলুন আমার কাছে পূর্ণসংখ্যার ভেক্টর রয়েছে:

std::vector<int> indices;
for (int i=0; i<15; i++) indices.push_back(i);

তারপরে আমি এটিকে সাজানো ক্রম অনুসারে বাছাই করেছি:

sort(indices.begin(), indices.end(), [](int first, int second) -> bool{return indices[first] > indices[second];})
for (int i=0; i<15; i++) printf("%i\n", indices[i]);

এটি নিম্নলিখিত উত্পাদন করে:

14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

এখন আমি 3, 4, 5 এবং 6 নম্বরগুলি শেষ পর্যন্ত স্থানান্তরিত করতে চাই এবং তাদের জন্য উতরিত ক্রমটি রাখি (পছন্দমতো sortদ্বিতীয়বার ব্যবহার না করে)। অর্থাৎ আমি যা চাই তা এখানে:

14
13
12
11
10
9
8
7
2
1
0
6
5
4
3

এটি std::sortঅর্জনের তুলনা কার্যটি আমি কীভাবে সংশোধন করব ?


4
return indices[first] > indices[second]মানে না return first < second;?
— acraig5075

2
একটি সহজ অবতরণ সাজানোর জন্য, std::greaterথেকে <functional>আপনার ল্যাম্বদার জায়গায় ব্যবহার করা যেতে পারে। আপনার প্রশ্নের হিসাবে, আরও ভার্বোজ তুলনামূলক লেখা যা আপনার মানগুলি যেভাবে চান তা তুলনা করে তা নিশ্চিত করার পক্ষে এটি করা সহজতম উপায়।
— মধ্যাহ্নে

4
@ acraig5075, অবতরণ ক্রমে এটি হওয়া উচিত return first > second।
— ks1322

1
@ acraig5075 আমার মনে আমি কিছু অনুপস্থিত করছি, অথবা মানুষের মধ্যে পার্থক্য জানেন না আরোহী এবং সাজানো ?
— sweenish

3
হয়তো আপনি খুঁজছেন std :: আবর্তন ?
— সুপার

উত্তর:


8

আপনার তুলনা ফাংশনটি ভুল যেহেতু আপনি যে মানগুলি পেয়েছেন firstএবং secondএটি উপাদান হিসাবে রয়েছে std::vector। সুতরাং এগুলি সূচক হিসাবে ব্যবহার করার দরকার নেই। সুতরাং, আপনি পরিবর্তন প্রয়োজন

return indices[first] > indices[second];

প্রতি

return first > second;

এখন, সমস্যাটি সমাধান করার চেষ্টা করুন ...

আপনি অন্যান্য উপাদানগুলির সাথে তুলনা ছাড়াই 3, 4, 5 এবং 6 রেখে যেতে পারেন এবং এখনও একে অপরের সাথে তুলনা করতে পারেন:

std::sort(
    indices.begin(), indices.end(),
    [](int first, int second) -> bool {
        bool first_special = first >= 3 && first <= 6;
        bool second_special = second >= 3 && second <= 6;
        if (first_special != second_special)
            return second_special;
        else
            return first > second;
    }
);

ডেমো


@ নটক্র্যাকার হ্যাঁ, আমি সম্মত হই যে শীর্ষস্থানীয় মানদণ্ডটি প্রথমে পাওয়া ভাল n
— স্তূপ ওভারফ্লো

5

থেকে কার্যাবলী মান আলগোরিদিম গ্রন্থাগার মত iota, sort, find, rotateএবং copyআপনার জীবন সহজ করতে হবে। আপনার উদাহরণ নীচে আসে:

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <iterator>


int main()
{
  std::vector<int> indices(15);
  std::iota(indices.begin(), indices.end(), 0);
  std::sort(indices.begin(), indices.end(), std::greater<>());

  auto a = std::find(indices.begin(), indices.end(), 6);
  auto b = std::find(indices.begin(), indices.end(), 3);
  std::rotate(a, b + 1, indices.end());

  std::copy(indices.begin(), indices.end(), std::ostream_iterator<int>(std::cout, "\n"));
  return 0;
}

আউটপুট:

14
13
12
11
10
9
8
7
2
1
0
6
5
4
3


মন্তব্যগুলিতে @ টেডলিঙ্গমো ভাল পয়েন্টটি দেয় যে এটি দিয়ে / উন্নত করা উচিত:

auto a = std::lower_bound(indices.begin(), indices.end(), 6, std::greater<int>{});
auto b = a + 4;

auto b = a + 4;ভুল (যদি আপনি পূর্ববর্তী স্নিপেটের সাথে ধারাবাহিকতা রাখতে চান)। এটি হওয়া উচিত auto b = a + 3;কারণ std::rotateআপনি ব্যবহার করছেনb + 1
— বিয়াজিও ফেস্টা

3

সমাধান ঘ

একটি অ-রৈখিক তুলনামূলক সঙ্গে সোজা পদ্ধতি ।

inline constexpr bool SpecialNumber(const int n) noexcept {
  return n < 7 && 2 < n;
}

void StrangeSortSol1(std::vector<int>* v) {
  std::sort(v->begin(), v->end(), [](const int a, const int b) noexcept {
    const bool aSpecial = SpecialNumber(a);
    const bool bSpecial = SpecialNumber(b);

    if (aSpecial && bSpecial) return b < a;
    if (aSpecial) return false;
    if (bSpecial) return true;
    return b < a;
  });
}

সমাধান 2

std::algorithmগুলি (পার্টিশন) ব্যবহার করে !

inline constexpr bool SpecialNumber(const int n) noexcept {
  return n < 7 && 2 < n;
}

void StrangeSortSol2(std::vector<int>* v) {
  auto pivot = std::partition(v->begin(), v->end(), std::not_fn(SpecialNumber));
  std::sort(v->begin(), pivot, std::greater{});
  std::sort(pivot, v->end(), std::greater{});
}

পারফরম্যান্স বিবেচনা

পার্টিশনের ওভারহেডের কারণে এটি দ্বিতীয় সমাধানটি ধীর গতির মতো দেখায়। সম্ভবত এটি আধুনিক প্রসেসরগুলিতে ক্যাশে এবং মিস-ব্রাঞ্চের পূর্বাভাসের কারণে নয়।

মাপকাঠি


যে কোনও ভাল সংকলক n <= 6 && 3 <= n টার্গেট সিপিইউর জন্য সবচেয়ে ভাল কাজ করে এমনটিতে রূপান্তরিত হওয়া উচিত যাতে আপনি 2 এবং 7 সংখ্যাটি দেখিয়ে কিছুই অর্জন করতে পারেন তবে সম্ভাব্য বিভ্রান্তি - এবং কেন রেফারেন্সের পরিবর্তে ভেক্টরটিতে কোনও পয়েন্টার নিন?
— টেড লিঙ্গমো

আর্গুমেন্ট ফাংশন হিসাবে `const int সংখ্যা` ব্যবহার করবেন না
— এন্টোইন মরিয়ার

1
@ এন্টাইনমুরিয়ার কেন?
— ওভারফ্লো

@ হিপ ওভারফ্লো কারণ কনস্ট্যান্ড ব্যবহার না করেই এটি সমান :)।
— এন্টোইন মরিয়ার

@ অ্যান্টাইনমারিয়র আমি এটি একরকম মনে করি না। constপাঠককে কি বলে না যে ফাংশনটি মান পরিবর্তন করে না? ওয়ান-লাইনারের এই বিশেষ ক্ষেত্রে এটি পরিষ্কার হতে পারে, তবে সাধারণভাবে তা হয় না।
— গাদা ওভারফ্লো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.