ใน 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
...