Those methods are a bit 'old school' now, and many here would discourage using them.
That said however, I'm 'old school' and have been doing dynamic allocation with raw (dumb) pointers for years, so I'm OK with it. I've also learned some of the newer 'safer' methods (using std::vector for instance) and I use them more and more.
By erasing some elements from each row you would need some way to keep track of the number of elements in each row, since this would vary from row to row.
I would allocate an extra row to int** array (with K elements ) and store the number of elements in each row there. This way,
number of elements in row r = array[size][r]
Here is some code for this.
I've stored the array data in a text file so the values can be read from there, instead of having to enter values by hand each program run.
I've stored the number of rows and columns as the 1st entries in the file. For the example you gave the file looks like this:
3 5
1 1 2 3 0
2 0 2 0 1
2 3 0 1 1
|
Here's my code, which worked for the case you gave but hasn't been tested any further:
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
#include <iostream>
#include <fstream>
#include <string>
// relegating tasks to functions (keeps main() simple)
int** Alloc_Init( unsigned& rows, const std::string& fileName );
void display( int** ppi, unsigned rows );
void eraseAllOf( int val, int** ppi, unsigned rows );
void DLT( int** ppi, unsigned rows );
int main()
{
unsigned ROWS = 0;
int** arr2D = Alloc_Init( ROWS, "test2.txt" );
if( arr2D )
{
display( arr2D, ROWS );
eraseAllOf( 0, arr2D, ROWS );
display( arr2D, ROWS );
DLT( arr2D, ROWS );
}
return 0;
}
int** Alloc_Init( unsigned& rows, const std::string& fileName )
{
int** ppi = NULL;
rows = 0;
unsigned cols = 0;
std::ifstream fin( fileName.c_str() );// Enter values by hand each time? No thanks!
if( fin )
{
fin >> rows >> cols;
unsigned r=0, c=0;
ppi = new int*[rows+1];// extra row for number of elements in each row
for(r=0; r<rows; ++r)
{
ppi[r] = new int[cols];
for(c=0; c<cols; ++c) ppi[r][c] = 0;
}
ppi[rows] = new int[rows];
for(r=0; r<rows; ++r) ppi[rows][r] = 0;// indicating 0 valid elements in each row initially
// get values from file
r = 0; c = 0;
while( fin >> ppi[r][c] && r < rows )
{
++c;
ppi[rows][r] = c;// increase valid element count
if( c%cols == 0 )
{
c = 0;
++r;
}
}
fin.close();
}
return ppi;
}
void display( int** ppi, unsigned rows )
{
for(unsigned r=0; r<rows; ++r)
{
for(int c=0; c < ppi[rows][r]; ++c)
std::cout << ppi[r][c] << ' ';
std::cout << '\n';
}
std::cout << '\n';
}
void eraseAllOf( int val, int** ppi, unsigned rows )
{
unsigned r=0;
int c=0;
for( r=0; r<rows; ++r )
{
int keepCount = 0;
for( c=0; c < ppi[rows][r]; ++c )
if( ppi[r][c] != val ) ++keepCount;
if( keepCount < ppi[rows][r] )
{
int* newRow = new int[keepCount];// new shorter row allocated
unsigned i = 0;
for( c=0; c < ppi[rows][r]; ++c )
if( ppi[r][c] != val ) newRow[ i++ ] = ppi[r][c];
delete [] ppi[r];// out with old row
ppi[r] = newRow;// keep the new row
ppi[rows][r] = keepCount;// new row length
}
}
}
void DLT( int** ppi, unsigned rows )
{
for(unsigned r=0; r<=rows; ++r)
delete [] ppi[r];
delete [] ppi;
}
|
It produces this output:
1 1 2 3 0
2 0 2 0 1
2 3 0 1 1
1 1 2 3
2 2 1
2 3 1 1
|
EDIT: Made some improvements to the code.