C ++ 20 में, <algorithm>
हेडर दो नए एल्गोरिदम प्राप्त करता है: shift_left()
औरshift_right()
। दोनों किसी भी LegacyForwardIterator को स्वीकार करते हैं। के लिए shift_left()
, यह निर्दिष्ट किया जाता है कि "चालें i
शुरू से बढ़ते क्रम में की जाती हैं 0
"; के लिए shift_right()
, यह निर्दिष्ट किया जाता है कि "यदि ForwardIt
LegacyBidirectionalIterator आवश्यकताओं को पूरा करता है, तो चालें 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
LegacyBidirectionalIterator आवश्यकताओं को पूरा करता है, तो मैं देख सकता हूं कि 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
...