2016-07-23 394 views
2

如何从矩阵中删除特定的行,保持相同的顺序? 例子:如何从C中的二维数组中删除一行?

1 1 1 
2 2 2 
3 3 3 

比方说,我需要与所有偶数元素删除行,所以删除后,它应该看起来像:

1 1 1 
3 3 3 

我试着写代码自己,(条件不一样我上面提到!)但它实际上并不能正常工作:

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--; 
    } 
} 
+0

这取决于你如何实现“2D数组”,但基本上通过删除列(你确定要删除列而不是行吗?)或在列之后移动列,覆盖要删除的列。 – MikeCAT

+0

排*,对不起 –

+0

情况看起来很奇怪。请发布[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)。 – MikeCAT

回答

3

,因为你修改的地方矩阵您的方法不起作用,更新i索引和相应的行数no_of_rows,但未能更新单独的数组prosjeci。每当某行匹配过滤器时,矩阵中的所有后续行都将被删除。

您可以通过使用矩阵单列索引和过滤器阵列解决这个问题:

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--; 
    } 
} 

或者,如果你能更新过滤数组,你可以这样做:

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

我没有看到你的代码有什么问题。

在评论中,有人要求您发布“最小,完整和可验证的示例”。这就是这个意思。我充实了你的程序,增加了你的matrica数组和其他变量的声明和初始化,改变条件来匹配你的例子,并在最后打印出数组。我结束了这个:

#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"); 
    } 
} 

因此,如果你在第一个地方发布了类似的东西会更好。

但是,当我编译和运行这个程序,它完美的作品。 (我并不感到惊讶 - 正如我所说的,我没有看到任何问题。)

所以无论你的问题是什么,它是在你没有向我们展示的东西。当你说“它实际上不能正常工作”时,你的意思是什么?你期望看到什么,而你看到了什么?

[P.S.你的问题还有一个问题。在你问得更好之前,我甚至不应该回答它。我的这个答案实际上是低调提醒我这个事实。我没有抱怨;我预料到了。但请,问一个更完整,交代问题,下一次。]

+0

现在看起来像对我的答案。对不起,这里我们不得不manny分享教程的人,所以并不代表这样的事情。 – Michi

+0

@Michi没问题。 –

+0

@SteveSummit 你说得对,问题出在“我没有告诉你的东西”,谢谢:) –

0

我试图做你的意思..

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; 
} 
1

首先,事实上,如果不创建数组的新副本,您不能删除数组中的元素。您只能用其他值覆盖它们,并将实际使用的元素数保存在数组中。

下面是一个演示程序,显示如何完成。名称为n的变量用于保留数组中实际使用的元素行数。

#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; 
} 

程序输出是

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 

至于你的方法,那么它是低效的,因为与检查的条件,而不是复制数组中的所有行给定行后只复制一个每次迭代行。

此外,同时更改for循环体内和for语句本身的控制变量是一种不好的做法。这使得难以阅读代码。

+0

return i == n;有趣的回报声明。 – Michi