Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 321
  • Last Modified:

How do I delete a row (one array) from a two dimensional matrix, in C++ code

void Marble::find_marble()
{
  //  while(num_marbles > 0)
  //  {
    for(int i = 1; i <= num_marbles; i++)
    {
       for(int j = 0; j < 20; j++)
       {
          if(sphere[i][j] == color)
          {
            delete [] sphere[i];
          }                                  
        }
    }

I am writing the marble game where players choose a color and if they are correct the marble(array in the matrix) is removed.  Each marble has twenty possible colors in it chosen at random with a random number generator.
The sample code above does not work to remove an array from the dynamically allocated two dimensional array called "sphere".
How do I delete a row(array) from a two dimensional matrix??
0
ap39769
Asked:
ap39769
  • 4
  • 3
  • 2
  • +2
2 Solutions
 
n_fortynineCommented:
you don't need all that complication. just create a "lock" (integer) to let the program know if a "row" should/should not be accessible. Initially keep all locks open, if you've decided that a row is no longer needed, "lock" it (of course this adds a little overhead to your program by having to check this "lock" everytime a row is to be accessed, but I guess it won't cost too much). does this sound doable?
0
 
wide_awakeCommented:
I think you'll have to create a new array with one less row, then copy all the data from the old array to the new one.
0
 
n_fortynineCommented:
wide_awake, that's more or less inefficient. what he's doing does not require the row to be *physically* removed from the array (if the marbles match, the row is "removed" and that's all).

the reasons why i suggest such a solution can be named: first, deleting the array like he did does not automatically "correct" the column indexes i.e. there would be one invalid index so the deleting really does not contribute anything to the concept of removal after all. Secondly, overwriting data from latter rows onwards is obviously a bad choice (you can see why) - copying data to a *new* array is even worse. And so on.

So what I was suggesting is to either keep another array of "locks" running separately from the "sphere," or maybe just allocate one more position in each row (use [0] for example - so instead of size 20, size 21). there might eventually be a better solution than this, but I'm certainly not in favor of copying "the old array to the new one."
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
wide_awakeCommented:
Copying the whole array each time is certainly not the most efficient way to do it, but it is the only way to *really* delete the row.

If just "hiding" a row is good enough, then your method will work, and will work much faster :)

Since it looks like your row width is fixed, you could create a struct that contains an array of ints (a row), as well as a flag for valid.  Then your sphere[] array would just be a 1-dimensional array of row structs.  

You could set rows to be valid by setting
sphere[i].valid = 1;

or access the "colors" value by using
sphere[i].colors[j] = color;

-Mark.
0
 
n_fortynineCommented:
>> but it is the only way to *really* delete the row
even if the row really has to be removed from the array, it's still not good to copy the entire array. What you'll do then is "rippling" the rows. e.g.

[0] ...
[1] ...
[2] ...
...
[n] ...

to *delete* row like you said, would only require copying row 3 onto 2, 4 onto 3 and so on, there is no point to even create anything else copy to. That's simply out of the question.

>> create a struct
well, it's one way to go about it. Using an array to do this would simplify the notation and coding (if he uses a struct he'll have to go back to the start, otherwise he'll only have to modify the existing code to check this array)
Either way is fine.
0
 
n_fortynineCommented:
>> to *delete* row like you said
please read: to *delete* row [2]
0
 
wide_awakeCommented:
I was thinking that the array would be the wrong size if you just "rippled" the entries up, but I guess that doesn't matter as long as you keep track of how many entries are in the array.

0
 
Mayank SAssociate Director - Product EngineeringCommented:
ap39769,

You cannot use delete [] to delete an array which was not allocated using new, but simply declared as 'int sphere[10][10] ;', if that's the case here.

The best thing to do is to move/ shift the rows up by 1 so that the row to be deleted is over-written by the one below it, and keep doing it till the last row, and then decrement the variable holding the number of rows by 1.

for ( i = 0 ; i < num_marbles ; i ++ )
     for ( j = 0 ; j < 20 ; j ++ )
          if ( sphere[i][j] == color )
          {
               for ( k = i ; k < num_marbles - 1 ; k ++ )
                    for ( l = 0 ; l < 20 ; l ++ )
                         sphere[k][l] = sphere[k+1][l] ; // end if, fors
                         
               num_marbles -- ; // decrement the number of rows by 1
               
          } // end if, outer fors

How-ever, if the 2-D array was actually a pointer-to-a-pointer, and allocated as:

int ** sphere ;

sphere = new (int *)[num_marbles] ;

for ( i = 0 ; i < num_marbles ; i ++ )
     sphere[i] = new int[20] ; // end for
     
Then, I would suggest that you modify the pointers such the first ( num_values - 1 ) hold the relevant rows, and the last one holds the row to be deleted, and then deallocate it using 'delete[]'.

int * temp ;

for ( i = 0 ; i < num_marbles ; i ++ )
     for ( j = 0 ; j < 20 ; j ++ )
          if ( sphere[i][j] == color )
          {
               temp = sphere[i] ;
               
               for ( int k = i ; k < num_marbles - 1 ; k ++ )
                    sphere[k] = sphere[k+1] ; // end if, fors
                         
               sphere[k] = temp ;
               delete [] sphere[k] ;
               num_marbles -- ; // decrement the number of rows by 1
               
          } // end if, outer fors


Hope that helps!

Mayank.
0
 
fl0ydCommented:
Why not use c++ instead:

typedef std::vector< std::vector< int > > int_matrix;
int_matrix sphere;

Now you can easily remove any given row by first getting an iterator and then applying

sphere.erase( it );

Even though not strictly necessary you can avoid memory reallocations by calling reserve( num_marbles ) on the inner vectors to. Access can be achieved much like in the c-like pointer-to-pointer implementation by writing

if( sphere[i][j] == color ) ...

.f
0
 
CleanupPingCommented:
ap39769:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Split points between mayankeagle, fl0yd and n_fortynine.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now