C++ Algorithm remove_if function is used to eliminate all the elements that satisfy a predicate from a given range [first, last) without disturbing the order of the remaining elements.
- This function cannot alter the size of the container.
- It returns an iterator to the new end of the range.
- Remove is stable, means that the relative order of the elements that are not removed is remain unchanged.
Syntax
template <class ForwardIterator, class UnaryPredicate>
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred);
Parameter
A forward iterator indicating the position of the initial element in the range where elements are being deleted.
last: A forward iterator indicating the position immediately after the last element in the range from which elements are to be deleted.
The unary predicate function takes an element as an argument that needs to be fulfilled in order to replace the element's value.
Return value
A forward iterator indicating the updated end position (last) of the altered range, or the first element if the first and last positions are the same.
Complexity
The complexity increases linearly within the specified range [first, last), where the function pred is applied to every element, potentially leading to modifications in certain elements.
Data races
The elements within the range [first, last) are accessed and may be altered during the process.
Exception safety
This function will raise an exception if any errors occur during the evaluation of the predicate, element assignments, or iterator operations.
Note: The invalid parameters cause an undefined behavior.
Example 1
Let's explore a straightforward example to showcase the functionality of the remove_if method:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
bool IsOdd(int i)
{
return ((i % 2) == 1);
}
int main ()
{
vector <int> vec2 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//store the position of last element
vector <int>::iterator pend;
// Print original vector
cout << "\nOriginal vector : ";
for(int i=0; i < vec2.size(); i++)
cout << " " << vec2[i];
cout << "\n";
// remove_if function call
pend = remove_if (vec2.begin(), vec2.end() , IsOdd);
// Print the vector
cout << "After remove_if : ";
for ( vector<int> :: iterator q=vec2.begin(); q != pend; ++q)
cout << ' ' << *q;
cout << '\n';
return 0;
}
Output:
Original vector : 1 2 3 4 5 6 7 8 9 10
After remove_if : 2 4 6 8 10
Example 2
Let's see another simple example:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool greater6 ( int value ) {
return value >6;
}
int main( ) {
vector <int> v1, v2;
vector <int>::iterator Iter1, Iter2, new_end;
int i;
for ( i = 0 ; i <= 9 ; i++ )
v1.push_back( i );
int ii;
for ( ii = 0 ; ii <= 3 ; ii++ )
v1.push_back( 7 );
random_shuffle ( v1.begin( ), v1.end( ) );
cout << "Vector v1 is ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
// Remove elements satisfying predicate greater6
new_end = remove_if (v1.begin( ), v1.end( ), greater6 );
cout << "Vector v1 with elements satisfying greater6 removed is\n ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
// To change the sequence size, use erase
v1.erase (new_end, v1.end( ) );
cout << "Vector v1 resized elements satisfying greater6 removed is\n ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
return 0;
}
Output:
Vector v1 is ( 4 7 7 7 0 5 7 1 6 9 3 7 8 2 ).
Vector v1 with elements satisfying greater6 removed is
( 4 0 5 1 6 3 2 1 6 9 3 7 8 2 ).
Vector v1 resized elements satisfying greater6 removed is
( 4 0 5 1 6 3 2 ).
Example 3
Let's see another simple example:
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
typedef std::vector<std::string>::iterator iterator;
struct startsWithA : public std::unary_function<std::string, bool> {
bool operator() (std::string s)
{
if(s[0] == 'A')
{
return true;
}
else
return false;
}
};
void print(iterator b, iterator e)
{
iterator i;
for(i = b; i != e; i++)
{
std::cout << *i << " ";
}
std::cout << std::endl;
}
int main()
{
startsWithA s;
std::vector<std::string> v;
v.push_back("China");
v.push_back("India");
v.push_back("Korea");
v.push_back("America");
v.push_back("Australia");
v.push_back("Pakistan");
std::cout << "Vector : ";
print(v.begin(), v.end());
iterator i = remove_if(v.begin(), v.end(), s);
std::cout << "Vector : ";
print(v.begin(), i);
return 0;
}
Output:
Vector : China India Korea America Australia Pakistan
Vector : China India Korea Pakistan
Example 4
Let's explore another straightforward illustration demonstrating the elimination of all spaces within a string. This involves shifting all non-space characters to the left and subsequently deleting any excess spaces.
#include <algorithm>
#include <string>
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
string str1 = "Text with some spaces";
str1.erase(remove(str1.begin(), str1.end(), ' '),
str1.end());
cout << str1 << '\n';
string str2 = "Text\n with\tsome \t whitespaces\n\n";
str2.erase(remove_if(str2.begin(),
str2.end(),
[](unsigned char x){return std::isspace(x);}),
str2.end());
cout << str2 << '\n';
return 0;
}
Output:
Textwithsomespaces
Textwithsomewhitespaces