天天看點

《認清C++語言》のrandom_shuffle()和transform()算法

1)STL中的函數random_shuffle()用來對一個元素序列進行重新排序(随機的),函數原型如下:

template<class RandomAccessIterator>

   void random_shuffle(

      RandomAccessIterator _First, //指向序列首元素的疊代器

      RandomAccessIterator _Last  //指向序列最後一個元素的下一個位置的疊代器

   );

template<class RandomAccessIterator, class RandomNumberGenerator>

      RandomAccessIterator _First,

      RandomAccessIterator _Last,

      RandomNumberGenerator& _Rand //調用随機數産生器的函數

random_shuffle()是一個完全通用的算法,适用于内置資料類型和使用者自定義類型。同時,由于STL算法不僅适用于容器,也适用于序列,是以,random_shuffle()算法可用于内置數組。

執行個體代碼如下:

#include <iostream>

#include <vector>

#include <algorithm>

#include <string>

int main()

{

    //用于内置資料類型

    std::vector<int> vi;

    for(int i=0; i<100; i++)

    {

        vi.push_back(i);        

    }

    std::random_shuffle(vi.begin(), vi.end());

    std::vector<int>::iterator it;

    for(it=vi.begin(); it!=vi.end(); it++)

        std::cout<<*it<<std::endl;                  

    //用于使用者自定義類型

    std::vector<std::string> vs;

    vs.push_back(std::string("Sunday"));

    vs.push_back(std::string("Monday"));

    vs.push_back(std::string("Tuesday"));

    vs.push_back(std::string("Wednesday"));

    vs.push_back(std::string("Thursday"));

    vs.push_back(std::string("Friday"));

    vs.push_back(std::string("Saturday"));

    std::random_shuffle(vs.begin(), vs.end());

    for(int i=0; i<7; i++)

        std::cout<<vs[i]<<std::endl;       

    //用于數組

    char arr[6] = {'a', 'b', 'c', 'd', 'e', 'f'};

    std::random_shuffle(arr, arr+6);

    for(int i=0; i<6; i++)

        std::cout<<arr[i]<<" ";       

    }

    std::cout<<std::endl;

    system("pause");

    return 0;

}

2)STL中的函數transform()用來周遊一個容器裡面指定範圍的元素,并對這些元素執行指定的操作,函數原型如下:

template<class InputIterator, class OutputIterator, class UnaryFunction>

   OutputIterator transform(

      InputIterator _First1, //元素起始位置的輸入疊代器

      InputIterator _Last1, //元素結束位置的輸入疊代器

      OutputIterator _Result, //執行指定操作的元素的起始位置的輸出疊代器

      UnaryFunction _Func //執行的操作(函數)

template<class InputIterator1, class InputIterator2, class OutputIterator,

   class BinaryFunction>

      InputIterator1 _First1, //第一個操作範圍的元素起始位置的輸入疊代器

      InputIterator1 _Last1, //第一個操作範圍的元素結束位置的輸入疊代器

      InputIterator2 _First2, //第二個操作範圍的元素起始位置的輸入疊代器

      OutputIterator _Result, //最終範圍的元素的起始位置的輸出疊代器

      BinaryFunction _Func //執行的操作(函數)

上面第一個版本的算法對區間[_First1, _Last1]中的每個元素應用函數_Func,并将每次_Func傳回的結果存儲到_Result中;

第二個版本的算法以類似的方式運作,但它期望獲得兩個序列并逐次調用一個處理成對元素的二進制函數。

#include <functional>

// The function object multiplies an element by a Factor

template <typename T>

class MultiValue

private:

    T Factor;   //The value to multiply by

public:

    //Constructor initializes the value to multiply by

    MultiValue(const T& _val) : Factor(_val)

    //The function call for the element to be multiplied

    T operator()(T& elem) const

        return elem*Factor;               

};

    using namespace std;

    vector<int> v1, v2(7), v3(7);

    vector<int>::iterator it1, it2, it3;

    //Constructing vector v1;

    for(int i=-4; i<=2; i++)

        v1.push_back(i);       

    }   

    cout<<"Original vector v1=(";

    for(it1=v1.begin(); it1!= v1.end(); it1++)

        cout<<*it1<<" ";                   

    cout<<")."<<endl;

    //Modifying the vector v1 in place

    transform(v1.begin(), v1.end(), v1.begin(), MultiValue<int>(2));

    cout<<"The elements of the vector v1 multiplied by 2 in place gives:"

        <<"/n v1mod=(";

    for(it1=v1.begin(); it1!=v1.end(); it1++)

        cout<<*it1<<" ";                   

    //using transform to multiply each element by a factor of 5

    transform(v1.begin(), v1.end(), v2.begin(), MultiValue<int>(5));

    cout<<"Multiplying the elements of the vector v1mod/n"

        <<"by the factor 5 & copying to v2 gives:/n v2=(";

    for(it2=v2.begin(); it2!=v2.end(); it2++)

        cout<<*it2<<" ";                   

    //The second version of transform used to multiply the

    //elements of the vectors v1mod & v2 pairwise

    transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),

                          multiplies<int>());

    cout<<"Multiplying elements of the vectors v1mod and v2 pairwise "

        <<"gives:/n v3=( ";

    for(it3=v3.begin(); it3!=v3.end(); it3++)

        cout<<*it3<<" ";

程式運作後輸出如下:

Original vector  v1 = ( -4 -3 -2 -1 0 1 2 ).      
The elements of the vector v1 multiplied by 2 in place gives:      
v1mod = ( -8 -6 -4 -2 0 2 4 ).      
Multiplying the elements of the vector v1mod      
by the factor 5 & copying to v2 gives:      
v2 = ( -40 -30 -20 -10 0 10 20 ).      
Multiplying elements of the vectors v1mod and v2 pairwise gives:      
v3 = ( 320 180 80 20 0 20 80 ).