Deleting columns and rows in 2D vector

Nov 10, 2010 at 10:46pm
Hello,

I am struggling to delete one column and one row from a 2D vector, where the column and row to be deleted depend on the position of the element, not its contents.

Without using an iterator I can delete a row, but not a column:
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
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main ()
{

int i, j, p;
int num =2;    //Row and column number to be deleted

vector<vector<int> > k;

for(i = 0; i <=5; ++i) 				//Fill vector k
	{
	k.push_back(vector<int>());
	for(j = 1; j <=6; j++)
	k[i].push_back(j);
		}

for (i=0; i< k.size(); ++i)			//Erases row number 2
		{
		if (i == num)
			{
			k.erase(k.begin()+i);
			}
		}


for (int x=0; x< k.size(); ++x)		//print vector
	{
	for (int y=0; y< k[x].size(); ++y)
		{
		cout << k[x][y] <<"\t";			
		}
	cout << endl;
	}							


My attempt to delete a column isn't working:
1
2
3
4
5
6
7
8
9
10
for (int r=0; r< k.size(); ++r)						
		{
		for (int s=0; s< k[r].size(); ++s)
			{
			if (k[r][s]==k[r][num])
				{
				k.erase(k.begin() +s);
				}
			}
		}		
Nov 10, 2010 at 11:06pm
Your logic is wrong. k.erase(X) will aways delete a row. Assuming k[Row][Col]. Your use of single letters for naming objects is hideous.

You're also using way too much iteration in your code.

To delete a row:
1
2
3
4
5
unsigned rowToDelete = 2;
if (myVector.size() > rowToDelete)
{
  myVector.erase( myVector.begin() + rowToDelete );
}


To delete a column:
1
2
3
4
5
6
7
8
9
unsigned columnToDelete = 2;

for (unsigned i = 0; i < myVector.size(); ++i)
{
  if (myVector[i].size() > columnToDelete)
  {
    myVector[i].erase(myVector[i].begin() + columnToDelete);
  }
}

Last edited on Nov 10, 2010 at 11:07pm
Nov 10, 2010 at 11:21pm
Thank you very much! Sorry about the single letter names. I used them for simplicity, but they obviously don't read well.
Nov 11, 2010 at 12:25am
Simplicity is having names that correspond nicely to the functionality of the object. When you put your code down for 6mnths and come back too it; how easy will it be to read and follow?

All good (or even average) coding standards will emphasize the naming of variables to be applicable to their purpose.
Nov 11, 2010 at 2:30am
Fun:
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 <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

template <typename ContainerType, typename ContainerType::size_type N>
struct delete_column
  {
  void operator () ( ContainerType& container )
    {
    typename ContainerType::iterator iter = container.begin();
    std::advance( iter, N );
    container.erase( iter );
    }
  };

const char* DATA[ 4 ][ 4 ] = 
  {
  { "0,0", "0,1", "0,2", "0,3" },
  { "1,0", "1,1", "1,2", "1,3" },
  { "2,0", "2,1", "2,2", "2,3" },
  { "3,0", "3,1", "3,2", "3,3" },
  };

std::ostream& operator << ( std::ostream& outs, const std::vector <std::vector <std::string> > & v )
  {
  for (unsigned r = 0; r < v.size(); r++)
    {
    outs << "Row " << r << ":  ";
    for (unsigned c = 0; c < v[ r ].size(); c++)
      outs << v[ r ][ c ] << " ";
    outs << std::endl;
    }
  return outs;
  }

int main( int argc, char** argv )
  {
  using namespace std;
  vector <vector <string> > data;

  for (unsigned n = 0; n < 4; n++)
    data.push_back( vector <string> ( DATA[ n ], DATA[ n ] + 4 ) );

  cout << data << endl;

  cout << "Row 2 deleted:\n";
  data.erase( data.begin() + 2 );
  cout << data << endl;

  cout << "Column 3 deleted:\n";
  for_each( data.begin(), data.end(), delete_column <vector <string>, 3> () );
  cout << data << endl;

  cout << "Column 1 deleted:\n";
  for_each( data.begin(), data.end(), delete_column <vector <string>, 1> () );
  cout << data << endl;

  cout << "Column 0 deleted:\n";
  for_each( data.begin(), data.end(), delete_column <vector <string>, 0> () );
  cout << data << endl;

  cout << "Column 2 deleted:\n";
  for_each( data.begin(), data.end(), delete_column <vector <string>, 0> () );  // it's really column 0 now...
  cout << data << endl;

  return 0;
  }
Topic archived. No new replies allowed.