সি ++ ২০ এ, <algorithm>
শিরোনামটি দুটি নতুন অ্যালগরিদম অর্জন করেছে: shift_left()
এবংshift_right()
। উভয়েই কোনও লিগ্যাসি ফরওয়ার্ডআইট্রেটর গ্রহণ করে। কারণ shift_left()
, এটি নির্দিষ্ট করা আছে যে "চালগুলি i
শুরু থেকে ক্রমবর্ধমান ক্রমে সঞ্চালিত হয় 0
"; কারণ shift_right()
, এটি নির্দিষ্ট করা আছে যে "যদি ForwardIt
লিগ্যাসিবিডায়ারেশনালআইটরেটরের প্রয়োজনীয়তা পূরণ হয় তবে চালগুলি " i
থেকে শুরু করার ক্রমহ্রাসমান ক্রমে সঞ্চালিত হয় last - first - n - 1
"।
আমি কার্যকর করার পক্ষে যুক্তিসঙ্গত সহজ উপায় সম্পর্কে ভাবতে পারি shift_left()
:
template <typename ForwardIt>
constexpr inline ForwardIt shift_left(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n) {
if (n <= 0) return last;
ForwardIt it = first;
for (; n > 0; --n, ++it) {
if (it == last) return first;
}
return std::move(it, last, first);
}
যদি ForwardIt
লিগ্যাসিবিডায়ারেশনালআইট্রেটারের প্রয়োজনীয়তাগুলি পূরণ করে তবে আমি দেখতে পাচ্ছি যে shift_right()
এটি খুব একইভাবে প্রয়োগ করা যেতে পারে shift_left()
। যাইহোক, এটি shift_right()
কোনও ক্ষেত্রে বাই-ডাইরেক্টরিয়াল ফরোয়ার্ড ইটারেটরগুলির জন্য কীভাবে প্রয়োগ করতে পারে তা মোটেও পরিষ্কার নয় ।
আমি একটি অ্যালগরিদম বের করেছি যা [first, first+n)
উপাদানগুলির অদলবদলের জন্য স্ক্র্যাচ স্পেস হিসাবে স্থানটি ব্যবহার করে, তবে এটি shift_left()
উপরের অ্যালগরিদমের চেয়ে কিছুটা অপব্যয়যুক্ত বলে মনে হচ্ছে :
template <typename ForwardIt>
constexpr inline ForwardIt shift_right(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n) {
if (n <= 0) return first;
ForwardIt it = first;
for (; n > 0; --n, ++it) {
if (it == last) return last;
}
ForwardIt ret = it;
ForwardIt ret_it = first;
for (; it != last; ++it) {
std::iter_swap(ret_it, it);
ret_it++;
if (ret_it == ret) ret_it = first;
}
return ret;
}
বাস্তবায়নের shift_right()
কি আরও ভাল বা "উদ্দেশ্যপ্রণোদিত" উপায় থাকবে ?
std::move
পরিবর্তে বাস্তবায়নটি ব্যবহার করা হবেstd::copy
...