如何从C中删除2D数组中的行?

时间:2016-07-23 10:58:48

标签: c arrays sorting 2d

如何从矩阵中删除特定行,保持相同的顺序? 示例:

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

4 个答案:

答案 0 :(得分:4)

我的代码没有任何问题。

在评论中,有人要求您发布一个&#34;最小,完整和可验证的示例&#34;。这意味着什么。我充实了你的程序,添加了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");
    }
}

如果您首先发布类似的内容会更好。

但是当我编译并运行这个程序时,它运行得很好。 (我并不感到惊讶 - 正如我所说,我没有看到任何错误。)

所以无论你遇到什么问题,它都会出现在你无法向我们展示的东西中。当你说&#34;它实际上没有正常工作时你是什么意思&#34;?你期望看到什么,你看到了什么?

[P.S。您的问题还有一个问题。直到你问得更好,我甚至不应该回答它。我的这个答案实际上是用来提醒我这个事实的。我没有抱怨;我期待它。但请在下次问一个更完整,更负责任的问题。]

答案 1 :(得分: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 :(得分: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循环的控制变量也是一种不好的做法。这使得难以阅读代码。

答案 3 :(得分: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;
}