C++ STL 中的修改算法

原文:https://www.studytonight.com/cpp/stl/stl-modifying-algorithms

以下是我们将介绍的标准模板库中的一些修改算法:

  • 复制和复制 _n
  • 填充和填充 _n
  • 移动
  • 改变
  • 产生
  • 交换
  • 交换范围
  • 反面的
  • 反向复制
  • 辐状的
  • 独一无二的
  • 唯一副本

copycopy_n

让我们从copy方法开始,逐一介绍每种方法:

copy方法

这个方法将元素从两个迭代器第一个最后一个定义的范围复制到迭代器第一个 2 开始的范围。

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    vector<int> v1,v2;

    v1.push(2);
    v1.push(4); 
    v1.push(6);
    v1.push(8);
    v1.push(10);

    **copy**(v1.begin(), v1.end(), v2.begin());

    */* v2 is now 2,4,6,8,10 */*
}

copy_n方法

该函数将第一个 n 元素从迭代器首先定义的位置复制到迭代器第一个 2 开始的范围内。

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    int values[] = {1,2,3,4,5,6,7,8,9}; 
    vector<int> **v1**(values, values+9), **v2**;

    **copy_n**(v1.begin(), 5, v2.begin()); *// copies first 5 elements from v1 to v2.*
    /* v2 is now 1,2,3,4,5 */ 
}

fillfill_n

让我们从fill方法开始,逐一介绍每种方法:

fill方法

这个方法在两个迭代器第一个最后一个定义的范围内给元素赋值。 fill() 的语法是,fill(iterator first, iterator last, int value)

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    vector<int> v1(10); *// v1 is now 0,0,0,0,0,0,0,0,0,0*

    **fill**(v.begin(), v.end(), 5);

    */* now v1 is 5,5,5,5,5,5,5,5,5,5 */*

    **fill**(v.begin(), v.end() - 5, 3);

    */* now v11 is 3,3,3,3,3,5,5,5,5,5 */*
}

fill_n方法

这个方法从迭代器第一个定义的位置给第一个 n 个元素一个给定值。 fill_n 的语法为fill_n(iterator first, iterator last, int value)

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    int values[] = {1,2,3,4,5,6,7,8,9}; 
    vector<int> v1(values, values+9);

    **fill_n**(v1.begin(), 5 ,10);
    */* v1 is now 10,10,10,10,10,6,7,8,9 */* 
}

move方法

该方法将元素从当前容器中移出,并返回其参考。移动的语法是move(element)。move()在 C++ 11 及更高版本中可用。

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    string a = "nicky";
    string b = "Vicky";

    vector<string> **name**;

    // inserts "nicky" in name , a is still = nicky
    name.push_back(a);        
    // inserts "Vicky" in name , b is now NULL
    name.push_back(**move**(b));  
}

transform

transform 对给定的范围应用一元/二元运算,并将结果复制到从迭代器 res 开始的范围中。transform()有两种版本,它们因对元素执行的操作类型而异。

  • transform(iterator first1, iterator last1, iterator res, unaryoperation op):此方法对范围【first1,last1】内的元素执行一元运算 op ,并将结果存储在从 res 开始的范围内。
  • transform(iterator first1, iterator last1, iterator first2, iterator res, unaryoperation op):该方法对范围【first1,last1】内的元素执行二进制运算 op ,范围内的元素从迭代器 first2 开始,并将结果存储在范围 res 开始。
#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int **unaryoperation** (int a)
{
    return a*2;
}

int main()
{
    vector<int> v1;
    vector<int> v2;
    vector<int> res1;
    vector<int> res2;

    for(int i=0; i < 10; i++)
    {
        v2.push_back(i);
        v1.push_back(i*10); 
    }

    */*   v2 : 1,2,3,4,5,6,7,8,9  */* 
    */*   v1 : 10,20,30,40,50,60,70,80,90  */*

    res2.resize(10);

    transform(v2.begin(), v2.end(), res1.begin(), unaryoperation);
    */* now res1 is : 2,4,6,8,10,12,14,16,18 */*
}

generategenerate_n

让我们从generate方法开始,逐一介绍每种方法:

generate方法

此方法将给定范围内的所有元素分配给对函数 generate_element 的连续调用所返回的值。生成的语法是generate(iterator first, iterator last, generator_function generate_element)

generate_n方法

该方法将给定范围内的第一个 n 元素赋给对函数 generate_element 的连续调用所返回的值。生成的语法为generate(iterator first, int n, generator_function generate_element)

#include <iostream>     
#include <algorithm>
#include <vector>
#include <time.h>
#include <cstdlib>

using namespace std;

int **generate_random**()
{
    return rand()%10;
}

int main()
{
    **srand**(time(NULL));

    vector<int> v1 , v2;
    v1.resize(10);
    v2.resize(10);

    **generate**(v1.begin(), v1.end(), generate_random) ;

    */* this assign each element a random value generated 
    by the generate_random() */*

    **generate_n**(v2.begin(), 5, generate_random);

    */* this assign first 5 elements a random value 
    and rest of the elements are un changed */* 
}

swap方法

此方法交换两个相同类型容器的元素。

#include <iostream>     
#include <utility>
#include <vector>

using namespace std;

int main ()
{
    int a = 6;
    int b = 9;

    **swap**(a,b);
    */* a = 9 , b=6 */* 

    */* you can also swap an entire container with swap */*

    vector<int> **v**, **c**;
    for(int j=0; j < 10; j++)
    {
        v.push_back(j);
        c.push_back(j+1);
    }

    **swap**(v,c);

    for(vector>int>::iterator i = **v**.begin(); i! = **v**.end(); i++)
    cout<<*i<<" ";

    cout<<endl;

    for(vector<int>::iterator k = **c**.begin(); k! = **c**.end(); k++)
    cout<< *k <<" ";
}

swap_ranges方法

swap_ranges(iterator first1, iterato last1, iterato first2):从第一个 2 开始,它将范围【第一个 1,最后一个 1】中的元素与范围中的元素交换。

#include <iostream>     
#include <utility>
#include <vector>

int main ()
{
    vector<int> v, c;
    for(int j=0; j < 10; j++)
    {
        v.push_back(j);
        c.push_back(j+1);
    }

    **swap_ranges**(v.begin(), v.begin()+5, c.begin());

    */* swaps the first five element of 
    vector v by the elements of vector c */*

    for(vector<int>::iterator i = v.begin(); i!= v.end(); i++)
    cout<< *i <" ";

    cout<<endl;

    for(vector<int>::iterator k = c.begin(); k!= c.end(); k++)
    cout<<*k<<" ";
}

reverse方法

reverse(iterator first, iterator last)用于反转范围内元素的顺序[第一个,最后一个]。

#include <iostream>     
#include <algorithm>
#include <vector>

using namespace std;

int main () 
{
    int a[] = {1,5,4,9,8,6,1,3,5,4};

    **reverse**(a, a+10);

    */* reverse all the elements of the array a*/ 
    /* now a is : 4,5,3,1,6,8,9,4,5,1 */*

    **reverse**(a, a+5);

    */* reverse first 5 elements of the array a */
    /* now a is : 6,1,3,5,4,8,9,4 */* 

    vector<int> v(a, a+10);

    **reverse**(v.begin(), v.end());

    */* reverse the elements of the vector v */
    /* vector is now 4,9,8,4,5,3,1,6 */*
}

reverse_copy方法

此方法以相反的顺序复制给定范围内的元素。它不会改变原始容器的顺序。 reverse_copy 的语法是reverse_copy(iterator first ,iterator last ,iterator res),通过迭代器 res 以相反的顺序将范围【第一个,最后一个】中的元素复制到范围中。

#include <iostream>     
#include <algorithm>
#include <vector>

using namespace std; 

int main()
{
    int values[] = {1,4,8,9,5,6,2,7,4,1};

    vector<int> v1(values, values+10);
    */* v1 is now 1,4,8,9,5,6,2,7,4,1  */*

    vector<int> v2;

    v2.resize(v1.size());   *// allocate size for v2*

    **reverse_copy**(v1.begin(), v1.end(), v2.begin());
    */* copies elements of v1 in reverse order in v2 */* 

    */* now v2 is : 1,4,7,2,6,5,9,8,4,1  */*
}

rotate方法

该方法用于rotate(iterator first, iterator middle, iterator last)给定范围【第一个,最后一个】内的元素,使得中间迭代器指向的元素成为第一个元素。

#include <iostream>     
#include <algorithm>
#include <vector> 

using namespace std;

int main () 
{
    int a[] = {1,5,9,8,4,6,9,2};
    vector<int> v(a,a+8);

    **rotate**(a,a+4,a+8);
    */* rotate a such that a[4] is now the first element of array a */
    /* now a is : 4,6,9,2,1,5,9,8 */*

    **rotate**(v.begin(), v.begin()+5, v.end());
    */* now vector v is :6,9,2,1,5,9,8,4  */*
}

unique方法

此方法从给定范围中移除连续的重复元素。它有两种变体。它将迭代器返回到新范围最后一个元素的旁边。resize()可用于调整容器尺寸后的唯一()。

  • unique(iterator first, iterator last):除了[第一个,最后一个]范围内的第一个元素外,删除所有连续的重复元素。运算符==,用于检查金属线是否重复。
  • unique(iterator first, iterator last, bool compare_function):在这个版本中,我们使用 compare_function 来检查元素是否重复。
#include <iostream>     
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;

bool **cmp_function**(int a , int b )
{
    return a+b;
}

int main ()
{
    int values[] = {10,5,5,5,9,6,6,4,4};
    vector<int> v (values,values+9) , v4;

    vector<int>::iterator it;

    it = **unique**(v.begin(), v.end());
    */* vector v is now : 10,5,9,6,4,-,-,-,-  */*

    */* - indicates that the elements are removed from the vector 
    and next elements are shifted to their position */

    /* now it is pointing to the first occurrence of the “-“ in 
    the vector , i.e the position next to the last element (4) */

    /* adjusting the size of vector v */*

    v.resize(distance(v.begin(),it));
    */* resize the vector by the size returned by distance function, 
    which returns the distance between the two iterators  */

    /* vector v is now 10,5,9,6,4  */

    /* using compare_function */*

    vector<int> v3(values, values+9);

    it = **unique**(v3.begin(), v3.end(), cmp_function);
    v3.resize(distance(v3.begin(), it));

    */* removes copies the duplicate  elements from v3*/*

    return 0;
}

unique_copy方法

此方法从范围[第一个,最后一个]复制唯一元素,并将迭代器返回到新范围中最后一个元素旁边的位置。它有两种变体。它将迭代器返回到新范围最后一个元素的旁边。resize()可用于调整容器尺寸后的唯一()。

  • unique_copy(iterator first, iterator last):除了[第一个,最后一个]范围内的第一个元素外,删除所有连续的重复元素。运算符==,用于检查金属线是否重复。
  • unique_copy(iterator first, iterator last, bool compare_function):在这个版本中,我们使用 compare_function 检查元素是否重复。
#include <iostream>     
#include <algorithm>
#include <vector>

using namespace std;

bool **cmp_fuction**(int a , int b )
{
    return a+b;
}

int main ()
{
    int values[] = {10,5,5,5,9,6,6,4,4};
    vector<int> v (values,values+9);
    vector<int> v2;
    v2.resize(v.size());

    vector<int>::iterator it;

    it = **unique**(v.begin(), v.end());
    */* vector v2 is now : 10,5,9,6,4,-,-,-,-  */

    /* - indicates that the elements are removed from the vector 
    and next elements are shifted to their position */

    /* now it is pointing to the first occurrence of the “-“ 
    in the vector, i.e the position next to the last element (4) */

    /* adjusting the size of vector v */*

    v.**resize**(distance(v.begin(), it));
    */* resize the vector by the size returned by distance function, 
    which returns the distance between the two iterators  */

    /* vector v is now 10,5,9,6,4  */

    /* using compare_function */*

    vector<int> v3(values,values+9),v4;
    v4.resize(v3.size());

    it = **unique_copy**(v3.begin(), v3.end(), v4.begin(), cmp_fuction);
    v4.resize(distance(v4.begin(), it));

    */* copies the unique elements from v3 to v4 */*

    return 0;
}