对STL 中算法rotate Random access iterator 源码理解
发布时间
阅读量:
阅读量
深入理解表中的具体实例能够帮助我们掌握相关知识。本书提供了该书中的源代码参考(如《STL源码解析》),通过查看代码进一步加深理解。
对random access iterator版rotate进行举例如:
| --- | --- | --- |
| 初始状态 | 1 2 3 4 5 6 7 8 9 | L1=3,L2=6,n=3,故需要循环处理3次 |
| n=3 | 1 2 6 45 978
起始位置为第3个数值时, ptr2如果经历了一系列递增的操作后返回到起始位置时,则会跳出循环(下同)|
| n=2 | 1 5 6 4 8 9 7 2 3
||
||
| n=1 | 4 5 6 7 8 9 1 2 3
||
||
||
||
||
||
| 初始状态
| 1 2 3 4 5 6 7 8 9
| L1=5,L2=4,n=1 故需要循环处理1次
| 初始状态
| 1 2 3 4 5 6 7 8
| L1=2,L2=6,n=2 故需要循环处理2次
| n=1 | 3 4 5 6 7 8 1 2 |
// 最大公因数,利用辗转相除法
// __gcd() 应用于 __rotate() 的 random access iterator 版
template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
while (n != 0) { //这里是一个迭代
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
}
// rotate 的 random access iterator 版
template <class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Distance*,
random_access_iterator_tag) {
// 以下迭代器的相减操作只使用于RandomAccessIterator
// 取全长和前段(移动的位数)的最大公因数
Distance n = __gcd(last - first, middle - first);
// 链数为gcd(m,n) 。链中元素个数为n/gcd(m,n)。
while (n--) //为了书写方便,先从最后一条链开始循环
__rotate_cycle(first, last, first + n, middle - first,
value_type(first));
}
template <class RandomAccessIterator, class Distance, class T>
void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator initial, Distance shift, T*) {
T value = *initial; //记下链首元素的值,接下来链首元素“出列”留下一个“槽”
RandomAccessIterator ptr1 = initial;
RandomAccessIterator ptr2 = ptr1 + shift;//指向链中下一元素
while (ptr2 != initial) {
*ptr1 = *ptr2;
ptr1 = ptr2; //ptr1指向“槽”的位置
if (last - ptr2 > shift) //还没有到达最后一个元素
ptr2 += shift;
else
ptr2 = first + (shift - (last - ptr2)); //此处可以将这个代数式解开发现如:ptr2=ptr2-翻转第二部分的长度 这样就非常好了理解了
}
*ptr1 = value;
}
// 分派函式(dispatch function)
template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last) {
if (first == middle || middle == last) return; //交换的中间点在首尾,返回
__rotate(first, middle, last, distance_type(first),
iterator_category(first));
}
//_copy版本的rotate
template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result) {
return copy(first, middle, copy(middle, last, result));
}
全部评论 (0)
还没有任何评论哟~
