主要函数有:
- rotate():循环移动元素。
- rotate_copy():复制序列时循环移动元素。
为了理解如何实现环移功能,可以将序列中的元素想象成手镯上的珠子。rotate() 操作会导致一个新元素成为开始迭代器所指向的第一个元素。在旋转之后,最后一个元素会在新的第一个元素之前。
rotate函数模板的行为等效于:
template <class ForwardIterator>
void rotate (ForwardIterator first, ForwardIterator middle,
ForwardIterator last)
{
ForwardIterator next = middle;
while (first!=next)
{
swap (*first++,*next++);
if (next==last) next=middle;
else if (first==middle) middle=next;
}
}
第一个参数是这个序列的开始迭代器;第二个参数是指向新的第一个元素的迭代器,它必定在序列之内。第三个参数是这个序列的结束迭代器。
例子:
已知序列1,2,3,4,5,6,7,8。要求每间隔1s循环显示一次,当按下任意键时,退出演示。
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <conio.h>
#include <time.h>
using namespace std;
void delay() { //实现1s延时程序
int start = time(NULL);
int end = start;
do {
if (start != end) //当start != end时时间流走的1s
break;
} while (end = time(NULL));
}
int main() {
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
vector<int> v(a, a + 8);
while (!_kbhit()) {
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
rotate(v.begin(), v.begin() + 1, v.end());
delay();
cout << endl;
}
return 0;
}
首先conio.h不是C标准库中的头文件,是vc下的一个头文件。结合rotate函数模板的原型,利用rotate函数很好地实现了循环显示, middle位置选为v.begin()+1。当第1次执行rotate时, middle指向元素⒉,所以结果是2,3,4,5,6,7,8,1;当第2次执行rotate时, middle指向3,所以结果是3,4,5,6,7,8,1,2。以下分析,以此类推。
延时程序delay应用了系统time函数,算法是:先获取当前时间秒数start,接着在while循环中不断读结束秒数end,当 start!= end时一定是过了1s。
按任意键退出用kbhit函数,用getch函数是不行的。因为_getch()函数的返回值是获取到的字符值。需要注意的是,_getch()函数是一个阻塞函数,直到有字符输入时才会返回,所以该函数不会返回错误值。
rotate_copy函数模板的行为等效于:
template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result)
{
result=std::copy (middle,last,result);
return std::copy (first,middle,result);
}
rotate_copy() 的前 3 个参数和 copy() 是相同的;第 4 个参数是一个输出迭代器,它指向目的序列的第一个元素。这个算法会返回一个目的序列的输出迭代器,它指向最后一个被复制元素的下一个位置。该函数功能是:一方面把*[middle,last)间元素依次存储到*[x,x+(last-middle))中,另一方面把*[first,middle)间元素依次存储到*[x+(last-middle),x+(last-first))中。
例子:
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main(){
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
cout<< "原始数据a[] = ";
copy(a, a + 8, ostream_iterator<int>(cout, " "));
cout<< endl;
list<int> v1(a, a + 8);
list<int>::iterator middle = v1.begin();
advance(middle, 3); //前移3位
rotate(v1.begin(), middle, v1.end());
cout<< "以4为中心环移(roate) : ";
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
cout<< endl;
list<int> v2(a, a + 8);
list<int> v3;
middle = v2.begin();
cout<< "以4为中心环移v2-->v3(reverse_copy) : ";
advance(middle, 3);
rotate_copy(v2.begin(), middle, v2.end(), back_inserter(v3));
copy(v3.begin(), v3.end(), ostream_iterator<int>(cout, " "));
return 0;
}
由于是 list容器,它的内部迭代器是双向迭代器,元素4的迭代器位置不能用middle= v2.begin()+3表示,只有随机迭代器如vector中的迭代器才能执行operate+(n)操作,但是可以用系统函数advance轻松实现。