remove_if

Hi everyone, I'm a new to c++ programming. I need some help to solve my task. I need to remove values (1 and 2) in 2d vector. I'm trying to use remove_if function but errors occurred. Hoping for someone to help me. Thank you.

Here is the input file:
0 4 8 9 5 11 10 2 12 7 3 6 1 0 0
0 10 11 9 8 5 4 1 7 3 6 12 1 0 0
0 0 8 9 5 4 11 10 2 12 7 3 6 1 0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  #include "stdafx.h"
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

//declare functions
void input();		//assign all input data into arrays
void remove();


//declare variables & files
const int pop_size = 3;				//population size
const int column_initialR = 15;		//number of column for initial route matrix

vector< vector <long double>> initial_route (column_initialR, vector <long double> (column_initialR,0));  //initial route 

int i, j;

//output files

 
void main() 
{
	input();
	remove();
	
}

void input()
{
	//open input files
	ifstream inpInitialRoute("myfile.txt");	//read initial route

	//assign initial routes into array                    
	for ( i = 0; i < pop_size; i++ )
	{
		for ( j = 0; j < column_initialR; j++)
		{
			inpInitialRoute >> initial_route[i][j];
			//cout << "Initial route [" << i << "][" << j << "] = " << initial_route[i][j] << endl;
		}
	}
	
	//close input files
	inpInitialRoute.close();
	//system("pause");
}

void remove()
{
	// decide value that will be removed
	bool removeVal( int i )          
	{
		return i == 1 || i == 2; 
	}
	
	// Eliminate values
	for (int i = 0 ; i < pop_size; i++)
	{
		for (int j = 0; j < column_initialR; j++)
       {
		   vector<int>::iterator it = remove_if( initial_route.begin(), initial_route.end(), removeVal);
	   }
	}

	//display 
	for (int i = 0 ; i < pop_size; i++)
	{
		for (int j = 0; j < column_initialR; j++)
		{
			cout << initial_route[i][j];
		}
		cout << endl;
	}
}
What are the errors which you are getting?

I believe that remove_if is defined in the <algorithm> header, which you don't have included. (although maybe remove_if is defined elsewhere too - I don't know).

Anyway, if you're able to say what errors you're getting then I'm sure that would be helpful to people trying to assist you.

You may also find this link helpful:
http://www.cplusplus.com/reference/algorithm/remove_if/
Last edited on
There are a number of errors in your code. You seem to be setting the size of the 2D vector incorrectly. Shouldn't it have pop_size rows? And you are declaring it with long double at first but then seem to think it contains ints later on. E.g., removeVal takes an int, and it shouldn't be declared inside a function anyway.

And you are using remove_if incorrectly. You should only be looping through the rows and then passing each row to remove_if (which loops through the columns automatically). Also, it shifts values over the removed values and returns the new end of the container, but you aren't doing anything with that information (such as reducing the size of the inner vectors).

However, I wonder if you really want to use remove_if at all. What do you expect it to do? For example, given your input, suppose you ran your program on it and it worked the way you wanted and you wrote the file back out. What would the result look like?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

const int PopSize = 3;
const int Columns = 15;

using InnerRoute = vector<int>;
using Route = vector<InnerRoute>;

void input(Route& route);
void remove(Route& route);
void print(Route& route);
 
int main() 
{
    Route route(PopSize, InnerRoute(Columns));
    input(route);
    print(route);
    cout << '\n';
    remove(route);
    print(route);
}

void input(Route& route)
{
    ifstream routeFile("myfile.txt");
    if (!routeFile)
    {
        cerr << "Cannot open input file\n";
        exit(EXIT_FAILURE);
    }
    for (size_t i = 0; i < route.size(); i++ )
        for (size_t j = 0; j < route[i].size(); j++)
            routeFile >> route[i][j];
}

void remove(Route& route)
{
    for (size_t i = 0 ; i < route.size(); i++)
    {
        auto it = remove_if(route[i].begin(), route[i].end(),
                        [](int i){ return i == 1 || i == 2; });
        route[i].erase(it, route[i].end());
    }
}

void print(Route& route)
{
    for (size_t i = 0 ; i < route.size(); i++)
    {
        for (size_t j = 0; j < route[i].size(); j++)
            cout << setw(3) << route[i][j] << ' ';
        cout << '\n';
    }
}

Output:
  0   4   8   9   5  11  10   2  12   7   3   6   1   0   0 
  0  10  11   9   8   5   4   1   7   3   6  12   1   0   0 
  0   0   8   9   5   4  11  10   2  12   7   3   6   1   0 

  0   4   8   9   5  11  10  12   7   3   6   0   0 
  0  10  11   9   8   5   4   7   3   6  12   0   0 
  0   0   8   9   5   4  11  10  12   7   3   6   0 
Last edited on

You may also find this link helpful:
http://www.cplusplus.com/reference/algorithm/remove_if/


Hi Cheddar99, I had try again using link provided, the error still occurred. How can I solved it. Hoping anyone can help me.

Error:
13:17: error: cannot convert 'int (*)[15]' to 'int*' in initialization
14:47: error: cannot convert 'int (*)[15]' to 'int*' in initialization

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_if

bool removeVal (int i) { return (i==1 || i==2); }

int main () {
  int myints[3][15] = { {0,4,8,9,5,11,10,2,12,7,3,6,1,0,0},
                     {0,10,11,9,8,5,4,1,7,3,6,12,1,0,0},
                     {0,0,8,9,5,4,11,10,2,12,7,3,6,1,0} };

  // bounds of range:
  int* pbegin = myints;                         
  int* pend = myints+sizeof(myints)/sizeof(int); 

  pend = std::remove_if (pbegin, pend, removeVal);   
                                                 
  std::cout << "the range contains:";
  for (int* p=pbegin; p!=pend; ++p)
    std::cout << ' ' << *p;
  std::cout << '\n';

  return 0;
}
Hi dutch, thank for your help. can i know what is size_t

1
2
    for (size_t i = 0; i < route.size(); i++ )
        for (size_t j = 0; j < route[i].size(); j++)


It is similar to

1
2
    for (int i = 0; i < route.size(); i++ )
        for (int j = 0; j < route[i].size(); j++)



What would the result look like?


The result should look like your result


  0   4   8   9   5  11  10  12   7   3   6   0   0 
  0  10  11   9   8   5   4   7   3   6  12   0   0 
  0   0   8   9   5   4  11  10  12   7   3   6   0
> can i know what is size_t

std::size_t https://en.cppreference.com/w/cpp/types/size_t

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_if, std::fill
#include <iterator>     // std::begin, std::end
#include <iomanip>      // std::setw

bool removeVal (int i) { return (i==1 || i==2); }

int main () {

  const std::size_t NROWS = 3 ;
  const std::size_t NCOLS = 15 ;

  int myints[NROWS][NCOLS] = { {0,4,8,9,5,11,10,2,12,7,3,6,1,0,0},
                               {0,10,11,9,8,5,4,1,7,3,6,12,1,0,0},
                               {0,0,8,9,5,4,11,10,2,12,7,3,6,1,0} };

  // range based loop: http://www.stroustrup.com/C++11FAQ.html#for
  for( auto& row : myints ) { // for each row in myints

      // remove 1 and 2 from this row
      // https://en.cppreference.com/w/cpp/iterator/begin
      const auto end_of_range = std::remove_if( std::begin(row), std::end(row), removeVal ) ;

      // print numbers till end of range of unremoved items
      for( auto iter = std::begin(row) ; iter != end_of_range ; ++iter )
          std::cout << std::setw(3) << *iter ;
      std::cout << '\n' ;
  }
}

http://coliru.stacked-crooked.com/a/d37f581a22aa7941
Hi dutch, i had see your codes. It hard for me to understand some of the term. And i had make some improvement at my previous code based on yours. I don't know either it right or wrong. 3 errors occurs when i run it.

(69) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
(69) : error C2440: 'initializing' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'int'
cpp(70) : error C2664: 'std::_Vector_iterator<_Ty,_Alloc> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Ty,_Alloc>,std::_Vector_const_iterator<_Ty,_Alloc>)' : cannot convert parameter 1 from 'int' to 'std::_Vector_const_iterator<_Ty,_Alloc>'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

//declare functions
void input();		//assign all input data into arrays
void remove();


//declare variables & files
const int pop_size = 3;				//population size
const int column_initialR = 15;		//number of column for initial route matrix

vector< vector <int>> initial_route (pop_size, vector <int> (column_initialR,0));  //initial route 

int i, j; 
 
void main() 
{
	input();
	remove();
}

void input()
{
	//open input files
	ifstream inpInitialRoute("myfile.txt");	//read initial route

	//assign initial routes into array                    
	for ( i = 0; i < pop_size; i++ )
	{
		for ( j = 0; j < column_initialR; j++)
		{
			inpInitialRoute >> initial_route[i][j];
			cout << "Initial route [" << i << "][" << j << "] = " << initial_route[i][j] << endl;
		}
	}
	
	//close input files
	inpInitialRoute.close();
}

bool removeVal(int i)
{
    return i == 1 || i == 2; 
}

void remove()
{
    for (i = 0 ; i < pop_size; i++)
    {
        auto it = remove_if(initial_route[i].begin(), initial_route[i].end(), removeVal);  //error here
        initial_route[i].erase(it, initial_route[i].end());									// also here
    }

    //display
	for (i = 0 ; i < pop_size; i++)
    {
        for (j = 0; j < column_initialR; j++)
            cout << setw(3) << initial_route[i][j] << ' ';
        cout << '\n';
    }
}


Hi JLBorges, thanks for your help. I would like to ask.

 
for( auto& row : myints ) { // for each row in myints 


 
const auto end_of_range = std::remove_if( std::begin(row), std::end(row), removeVal ) ;


What if my compiler dont support range based loop. how can i replace auto.
It looks like those errors are due to not compiling the code as C++11 (or later). Pre-C++11 you can't use the auto keyword in that way (it existed in the language but was basically useless).

You need to set your compiler to compile as C++11. I don't know how to do that for Windows. Someone else can hopefully tell you. Alternatively you can replace auto in your code with vector<int>::iterator
Last edited on
Hi dutch.

vector<int>::iterator


Its work but they only display the first row only and then debug assertion failed.

vector subscript out of range.
You need to use the current size of the vector, not the original column_initialR size:

1
2
3
4
5
6
    for (i = 0 ; i < pop_size; i++)
    {
        for (j = 0; j < initial_route[i].size(); j++)
            cout << setw(3) << initial_route[i][j] << ' ';
        cout << '\n';
    }

Its work. Thank you @dutch for your help.
Topic archived. No new replies allowed.