See the Tutorial List

Modifying Algorithms in C++ STL

Following are some Modifying algorithms in Standard Template library that we will be covering :

  • copy and copy_n
  • fill and fill_n
  • move
  • transform
  • generate
  • swap
  • swap_ranges
  • reverse
  • reverse_copy
  • rotate
  • unique
  • unique_copy

copy and copy_n

Let's cover each method one by one starting with copy method:


copy method

This method copies the elements from the range defined by two iterators first and last into the range starting by the iterator first2.

#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 method

This function copies the first n elements from the position defined by iterators first into the range starting by the iterator first2.

#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 */ 
}

fill and fill_n

Let's cover each method one by one starting with fill method:


fill method

This method assigns the element a given value in the range defined by two iterators first and last. Syntax for fill() is, 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 method

This method assingns the first n elements a given value from the position defined by iterator first. Syntax for fill_n is 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 method

This method moves the elements form the current container and return its rvalue reference. Syntax for move is move(element). move() is available in C++ 11 and above.

#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 applies a unary/binary operation on a given range and copies the result into the range starting from iterator res. There are two version of transform() which differ by the type of operations performed on the elements.

  • transform(iterator first1, iterator last1, iterator res, unaryoperation op): This method performs unary operation op on the elements in range [first1,last1] and stores the result in range starting from res.
  • transform(iterator first1, iterator last1, iterator first2, iterator res, unaryoperation op): This method performs binary operation op on the elements in range [first1,last1] with the elements in the range starting with iterator first2 and stores the result in range starting from 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 */
}

generate and generate_n

Let's cover each method one by one starting with generate method:


generate method

This method assigns all the elements in the given range to the value returned by the successive call to function generate_element. Syntax for generate is generate(iterator first, iterator last, generator_function generate_element).


generate_n method

This method assigns first n elements in the given range to the value returned by the successive call to function generate_element. Syntax for generate is 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 Method

This method swaps the elements of two container of same type.

#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 method

swap_ranges(iterator first1, iterato last1, iterato first2) : It swaps the elements in the range [first1, last1] with the elements present in the range starting from first2.

#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 method

reverse(iterator first, iterator last) is used to reverse the order of the elements in the range [first, 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 method

This method copies the elements in the given range in the reverse order. It does not change the order of the original container. Syntax for reverse_copy is reverse_copy(iterator first ,iterator last ,iterator res), copies the elements in the range [first, last] in the reverse order to the range starting by iterator 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 method

This method is used to rotate(iterator first, iterator middle, iterator last) the elements present in the given range [first,last] such that the element pointed by the middle iterator becomes first element.

#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 method

This method removes the consecutive duplicate elements from the given range. It have two variations. It returns an iterator to the position which is next to the last element of the new range. resize() can be used for adjusting the size of the container after unique().

  • unique(iterator first, iterator last) : It removes all the consecutive duplicate elements except the first one in the range [first,last]. Operator ==, is used to check if the elemets are duplicate or not.
  • unique(iterator first, iterator last, bool compare_function) : In this version, we use compare_function to check if the elememts are duplicate of not.
#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 method

This method copies the unique elements from the range [first,last] and returns the iterator to the position next to the last element in the new range. It have two variations. It returns an iterator to the position which is next to the last element of the new range. resize() can be used for adjusting the size of the container after unique().

  • unique_copy(iterator first, iterator last) : It removes all the consecutive duplicate elements except the first one in the range [first,last]. Operator ==, is used to check if the elemets are duplicate or not.
  • unique_copy(iterator first, iterator last, bool compare_function) : In this version, we use compare_function to check if the elememts are duplicate of not.
#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;
}