zoukankan      html  css  js  c++  java
  • STL中copy算法

    STL中通过使用copy函数以提供一种方便的方式来输出容器中的元素。函数copy作为泛型算法的一部分,任何容器类型都可以使用。由于我们需要频繁的初始容器的元素,因此在继续讨论容器之前,先学习一下copy函数的用法。


    copy函数不只是输出容器的元素。通常,它允许我们复制元素从一个地方到另一个地方。例如输出vector的元素或复制vector的元素到另一个vector,我们可以使用copy函数。该函数模版copy的原型为:

    template <class inputIterator, class outputIterator>
    outputIterator copy(inputIterator first1, inputIterator last, outputIterator first2);


    参数first1指定了开始拷贝元素的位置;参数last指定了结束位置。参数first2指定了拷贝元素到哪里。因此,参数first1和last指定了源;参数first2指定了目的。


    注意到在范围first1...last -1中的元素被拷贝。


    函数模版copy的定义包含在头文件algorithm中,因此,在使用函数copy时,程序必须包含如下语句:

    #include <algorithm>


    函数copy的工作流程如下:

    考虑如下的语句

    int intArray[] = {5, 6, 8, 3, 40, 36, 98,  29, 75};

    该语句创建了9个组件的数组intArray,这里,intArray[0] = 5, intArray[1] = 6,等等。

    语句:

    vector<int>  vecList(9);

    创建了9个类型为vector的组件的空容器,其元素类型为int,


    对于intArray,实际上是一个指针,包含数组的基地址。因此,intArray指向数组的第一个组件。intArray + 1指向数组的第二个组件,等等。


    现在,考虑如下的语句:

    copy(intArray, intArray + 9, vecList.begin());

    该语句复制从位置intArray开始的元素,从数组的第一个组件intArray开始,直到intArray + 9 -1(即为intArray + 8,其为数组intArray的最后一个元素)到容器vecList。(注:此处first1是intArray,last是intArray + 9,first2是vecList.begin())。执行copy后,vecList的内容如下:

    vecList = {5, 6, 8, 3, 40, 36, 98,  29, 75};

    接着,考虑如下语句:

    copy(intArray + 1, intArray + 9, intArray);

    此处,first1为intArray + 1,即first1指向数组intArray的第二个元素位置,last为intArray + 9。同时,first2为intArray;即first2指向数组intArray的第一个元素位置。因此,第二个数组元素复制到第一个数组组件,第三个数组元素到第二个数组组件,等等。当上面的语句执行后,intArray内容为:

    intArray[] = {6, 8, 3, 40, 36, 98,  29, 75, 75};

    很明显,数组intArray中的元素左移了一个位置。


    考虑如下语句:

    copy(vecList.rbegin() + 2, vecList.rend(), vecList.rbegin());

    其中rbegin(reverse begin)函数返回容器中最后一个元素的指针。用于以反向来对容器中元素进行处理。因此,vecList.rbegin() + 2返回容器vecList中倒数第三个元素的指针。相似地,rend(reverse end)函数返回容器中指向第一个元素的指针。

    所以,上边的语句把容器vecList中的元素右移两个位置。上述语句执行完后,容器vecList中的内容如下:

    vecList = {5, 6, 5, 6, 8, 3, 40, 36, 98}


    以下对一种特殊类型的iterator——ostream iterators进行描述,这些ostream iterators可以很好的利用copy函数来拷贝一个容器的元素到输出设备。


    ostream迭代器和copy函数

    输出容器内容的一种方法就是使用for循环,函数begin用来初始化for循环的控制变量,函数end用来设置上限。另一种方法是使用copy函数来输出容器元素。对于这种情况,类型为ostream的迭代器指定目标(destination)。当我们创建一个ostream类型的迭代器,我们也指定了迭代器将输出的元素类型。


    下列语句展示了如何创建一个类型为int的ostream迭代器:

    ostream_iterator<int> screen(cout, " ");


    该语句创建screen作为ostream迭代器(元素类型为int)。迭代器screen有两个参数:对象cout和空格(a space)。因此,迭代器screen使用对象cout来初始化。当该迭代器输出元素时,它们通过空格来分开。


    语句:

    copy(intArray, intArray + 9, screen);


    输出intArray中的元素到屏幕上。

    相似地,语句:

    copy(vecList.begin(), vecList.end(), screen);


    输出容器vecList里的元素到屏幕。
    我们将频繁的使用copy函数,通过ostream迭代器来输出容器中的元素。
    当然,我们可以直接在copy函数中指定一个ostream迭代器,因此对于上面的例子,可以直接写为:

    copy(vecList.begin(), vecList.end(), ostream_iterator<int>(cout, " "));


    最后,语句:

    copy(vecList.begin(), vecList.end(), ostream_iterator<int>(cout, ","));


    表示输出vecList中的元素,并以逗号(",")隔开。
    以下举例说明如何使用copy函数和ostream迭代器:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    
    using namespace std;
    
    int main()
    {
    	int intArray[] = {5, 6, 8, 3, 40, 36, 98, 29, 75};
    
    	vector<int> vecList(9);
    
    	ostream_iterator<int> screen(cout, " ");
    	cout << "intArray: ";
    	copy(intArray, intArray + 9, screen);
    	cout << endl;
    
    	copy(intArray, intArray + 9, vecList.begin());
    	cout << "vecList: ";
    	copy(vecList.begin(), vecList.end(), screen);
    	cout << endl;
    
    	copy(intArray + 1, intArray + 9, intArray);
    	cout << "After shifting the elements " << "one position to the left, " << endl
    		<< "		int Array: ";
    	copy(intArray, intArray + 9, screen);
    	cout << endl;
    	copy(vecList.rbegin() + 2, vecList.rend(), vecList.rbegin());
    	cout << "After shifting the elements "
    		<< "down by two positions, " << endl
    		<< "		vecList: ";
    	copy(vecList.begin(), vecList.end(), screen);
    	cout << endl;
    
    	return 0;
    }

    输出为:


  • 相关阅读:
    POJ1579Function Run Fun
    C++ 程序员必读书目清单
    zoj2100Seeding(水题)
    接口开发及技术负责
    哪些需求最重要
    地址
    哪些需求最重要
    setTimeOut与 setInterval区别
    项目管理简介
    项目管理简介
  • 原文地址:https://www.cnblogs.com/riasky/p/3429205.html
Copyright © 2011-2022 走看看