问题
How do I remove a specific row from a matrix, keeping the same order? Example:
1 1 1
2 2 2
3 3 3
Let's say I need to remove the row with all even elements, so after deleting it should look like:
1 1 1
3 3 3
I tried writing code myself, (condition not the same as i mentioned above!) but it doesn't actually work properly:
for (i = 0 ; i < no_of_rows ; i++) {
if (abs(prosjeci[i] - prosjek) < 0.1) { /* condition */
for (k = i ; k < no_of_rows - 1 ; k++) {
for (j = 0 ; j < no_of_columns ; j++) {
matrica[k][j] = matrica[k+1][j];
}
}
i--;
no_of_rows--;
}
}
回答1:
Your method does not work because you modify the matrix in place, update the i
index and the number of rows no_of_rows
accordingly, but fail to update the separate array prosjeci
. Whenever a row matches the filter, all subsequent rows in the matrix are removed.
You can fix this problem by using a separate index for the matrix and the filter array:
int ii; // index into the prosjeci array.
for (i = ii = 0; i < no_of_rows ; i++, ii++) {
if (abs(prosjeci[ii] - prosjek) < 0.1) { /* condition */
for (k = i; k < no_of_rows - 1; k++) {
for (j = 0; j < no_of_columns; j++) {
matrica[k][j] = matrica[k+1][j];
}
}
i--;
no_of_rows--;
}
}
Alternately, if you can update the filtering array, you can do this:
for (i = 0; i < no_of_rows ; i++) {
if (abs(prosjeci[i] - prosjek) < 0.1) { /* condition */
for (k = i; k < no_of_rows - 1; k++) {
for (j = 0; j < no_of_columns; j++) {
matrica[k][j] = matrica[k+1][j];
}
prosjeci[k] = prosjeci[k+1];
}
i--;
no_of_rows--;
}
}
回答2:
I don't see anything wrong with your code.
In the comments, someone asked you to post a "Minimal, Complete, and Verifiable example". Here's what that means. I fleshed out your program, adding a declaration and initialization of your matrica
array and other variables, changing the condition to match your example, and printing out the array at the end. I ended up with this:
#include <stdio.h>
int matrica[][3] = {
{1, 1, 1},
{2, 2, 2},
{3, 3, 3}
};
int no_of_columns = 3;
int no_of_rows = 3;
int main()
{
int i, j, k;
for (i = 0 ; i < no_of_rows ; i++) {
if (matrica[i][0] % 2 == 0) { /* even row */
for (k = i ; k < no_of_rows - 1 ; k++) {
for (j = 0 ; j < no_of_columns ; j++) {
matrica[k][j] = matrica[k+1][j];
}
}
i--;
no_of_rows--;
}
}
for (i = 0 ; i < no_of_rows ; i++) {
for (j = 0 ; j < no_of_columns ; j++) {
printf("%d ", matrica[i][j]);
}
printf("\n");
}
}
So it would have been better if you had posted something like that in the first place.
But when I compile and run this program, it works perfectly. (I'm not surprised -- as I said, I don't see anything wrong with it.)
So whatever your problem is, it's in something you haven't showed us. What did you mean when you said "it doesn't actually work properly"? What did you expect to see, and what did you see instead?
[P.S. There's one more problem with your question. Until you ask it better, I am not even supposed to answer it. This answer of mine was actually downvoted to remind me of this fact. I'm not complaining; I expected it. But please, ask a more complete and answerable question next time.]
回答3:
First of all in fact you can not remove elements from an array without creating a new copy of the array. You can only overwrite them with some other values and keep the number of actually used elements in the array.
Here is a demonstrative program that shows how it can be done. The variable with the name n
is used to keep the number of actually used rows of elements in the array.
#include <stdio.h>
#define N 10
int all_of_even( const int *row, size_t n )
{
size_t i = 0;
while ( i < n && row[i] % 2 == 0 ) i++;
return i == n;
}
int main(void)
{
int a[][N] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
{ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }
};
const size_t M = sizeof( a ) / sizeof( * a );
size_t n = M;
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
n = 0;
for ( size_t i = 0; i < M; i++ )
{
if ( !all_of_even( a[i], N ) )
{
if ( n != i )
{
for ( size_t j = 0; j < N; j++ ) a[n][j] = a[i][j];
}
++n;
}
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
return 0;
}
The program output is
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
1 1 1 1 1 1 1 1 1 1
3 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 5 5
7 7 7 7 7 7 7 7 7 7
9 9 9 9 9 9 9 9 9 9
As for your approach then it is inefficient because for each iteration with checking the condition you copy all rows of the array after the given row instead of copying only one row.
Also it is a bad practice to change control variables of a for loop in its body and in the for statement itself simultaneously. This makes difficult to read the code.
回答4:
i tried to do what you meant..
main(){
int matrica[3][3] = { { 1,2,3 },
{ 4,4,4 },
{ 7,8,9 } };
double no_of_rows = 3;
int line_removed = 0;
for (int i = 0; i < no_of_rows; i++) {
double sum = 0;
for (int j = 0; j < no_of_rows; j++)
{
sum = sum + matrica[i][j];
}
for (int j = 0; j < no_of_rows; j++)
{
int checker = 0.1 + (sum / no_of_rows);
if ( checker > matrica[i][j] || checker < matrica[i][j])
{
break;
}
if (j = (no_of_rows-1))
{
for ( int k = i ; k < no_of_rows; k++)
{
for ( j = 0; j < no_of_rows; j++)
{
matrica[k][j] = matrica[k + 1][j];
}
}
line_removed++;
}
}
}
for (int i = 0; i < (no_of_rows-line_removed); i++)
{
for (int j = 0; j < no_of_rows; j++)
{
printf("%d ", matrica[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
来源:https://stackoverflow.com/questions/38540980/how-to-delete-a-row-from-a-2d-array-in-c