如何删除用户在c中选择的二维数组的N个数和列?

时间:2021-10-03 19:20:07

I am writing a piece of code that uses a struct containing a 2d array and predetermined functions which I have listed with comments describing what the function does.

我正在写一段代码,它使用一个包含二维数组和预定函数的结构,我在上面列出了描述该函数的功能。

struct matrix
{
    char name;
    int mValues[10][10[;
    int nrows;
    int ncols;
};
/** Function Prototypes**/

// Lets user name, choose dimensions and populates matrix from a 10x10 .txt file
void matrixInput(struct matrix *matA); 

// Asks the user to choose how many rows to delete and select which rows 
// Asks the user to choose how many columns to delete and select which columns.
// The result should be a sub matrix of the input matrix stored in a new struct matrix
void subMatrix(struct matrix m1, struct matrix *m2);

// What the Input/Output should look like

How many rows do you want to delete? : 2

Please enter, one per row, the number(s) of the 2 rows you want to delete : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 1

How many columns do you want to delete? : 3

Please enter, one per column, the number(s) of the 3 columns you want to delete : 4
Please enter, one per column, the number(s) of the 3 columns you want to delete : 2
Please enter, one per column, the number(s) of the 3 columns you want to delete : 5

// Displays sub matrix 

It's the last function I am having problems with.

这是我最后一个问题。

I know the size of the input matrix and I think that I need to some how tell the complier pass the values of the input matrix to the new struct matrix while excluding the value of the user input for row/col number to be deleted. I'm not sure if this could be done in a nested loop or if I would need other variables to store values.

我知道输入矩阵的大小,我想我需要告诉编译器如何将输入矩阵的值传递给新的struct矩阵,同时不考虑要删除的行/col号的用户输入值。我不确定这是否可以在嵌套循环中完成,或者是否需要其他变量来存储值。

I know how to read and pass values at a given index but I'm stuck for ideas when it comes to not reading and passing values at a given index.

我知道如何在给定的索引中读取和传递值,但是当它在给定的索引中不读取和传递值时,我就会陷入其中。

Can anybody point me in the right direction?

有人能告诉我正确的方向吗?

Side note, any tips on how to improve the quality of my question is welcomed.

附注,任何关于如何提高我的问题质量的建议都是受欢迎的。

2 个解决方案

#1


1  

If you know which columns and rows to delete, and you are sure that the result is going to fit in the new matrix, then just do a nested loop and tell it to ignore a certain range of values.

如果您知道要删除哪些列和行,并且确定结果将适合新矩阵,那么只需做一个嵌套循环,并告诉它忽略一定范围的值。

But what you really want to do is create the new matrix inside the copying function and return it. If they are created dynamically you can ignore assignment of the columns or rows you are trying to copy in the same way (nested loops) and fit it exactly with the size you need.

但是你真正想做的是在复制函数中创建新的矩阵并返回它。如果它们是动态创建的,您可以忽略您试图以相同方式复制的列或行的分配(嵌套循环),并与所需的大小完全匹配。

#2


1  

You can't easily store delete information in a matrix, because matrix->values[0][0] could refer to either row or column. It's easier to declare to integers instead.

在矩阵中不能很容易地存储删除信息,因为矩阵->值[0][0]可以引用行或列。它更容易声明为整数。

The function void subMatrix(struct matrix m1,...) is technically okay if you don't want to change m1, but this makes an extra copy of m1 which is not efficient. It's better to use void subMatrix(const struct matrix *source,...) instead.

函数void子矩阵(struct matrix m1,…)从技术上来说是可以的,如果你不想改变m1,但是这会增加m1的额外副本,这是无效的。最好使用void子矩阵(const struct matrix *source,…)代替。

You can also use dynamic allocation instead of fixed array of value[10][10]. Example:

您也可以使用动态分配而不是固定的值数组[10][10]。例子:

struct matrix {
    int **data;
    int rows;
    int cols;
};

void create(struct matrix *m, int rows, int cols)
{
    m->rows = rows;
    m->cols = cols;
    m->data = malloc(rows * sizeof(int*));
    for(int r = 0; r < rows; r++)
        m->data[r] = malloc(sizeof(int) * cols);
}

void destroy(struct matrix *m)
{
    for(int i = 0; i < m->rows; i++)
        free(m->data[i]);
    free(m->data);
}

void print(const struct matrix *m)
{
    for(int r = 0; r < m->rows; r++)
    {
        for(int c = 0; c < m->cols; c++)
            printf("%4d", m->data[r][c]);
        printf("\n");
    }
    printf("\n");
}

void change(struct matrix *new, struct matrix *m, int *delete_rows, int *delete_cols)
{
    int rows = 0;
    for(int row = 0; row < m->rows; row++)
        if(!delete_rows[row])
            rows++;
    int cols = 0;
    for(int col = 0; col< m->cols; col++)
        if(!delete_cols[col])
            cols++;
    create(new, rows, cols);

    int next_row = 0;
    for(int row = 0; row < m->rows; row++)
    {
        if(delete_rows[row]) continue;
        int next_col = 0;
        for(int col = 0; col < m->cols; col++)
        {
            if(delete_cols[col]) continue;
            new->data[next_row][next_col] = m->data[row][col];
            next_col++;
        }
        next_row++;
    }
}

int main(void)
{
    struct matrix m;
    create(&m, 10, 10);
    for(int r = 0; r < m.rows; r++)
        for(int c = 0; c < m.rows; c++)
            m.data[r][c] = r * 100 + c;
    print(&m);

    //get delete information
    int delete_rows[10] = { 0 };
    int delete_cols[10] = { 0 };
    delete_rows[0] = 1;//delete row 0
    delete_cols[7] = 1;//delete col 7

    struct matrix new;
    change(&new, &m, delete_rows, delete_cols);
    print(&new);
    destroy(&m);
    destroy(&new);
    return 0;
}

#1


1  

If you know which columns and rows to delete, and you are sure that the result is going to fit in the new matrix, then just do a nested loop and tell it to ignore a certain range of values.

如果您知道要删除哪些列和行,并且确定结果将适合新矩阵,那么只需做一个嵌套循环,并告诉它忽略一定范围的值。

But what you really want to do is create the new matrix inside the copying function and return it. If they are created dynamically you can ignore assignment of the columns or rows you are trying to copy in the same way (nested loops) and fit it exactly with the size you need.

但是你真正想做的是在复制函数中创建新的矩阵并返回它。如果它们是动态创建的,您可以忽略您试图以相同方式复制的列或行的分配(嵌套循环),并与所需的大小完全匹配。

#2


1  

You can't easily store delete information in a matrix, because matrix->values[0][0] could refer to either row or column. It's easier to declare to integers instead.

在矩阵中不能很容易地存储删除信息,因为矩阵->值[0][0]可以引用行或列。它更容易声明为整数。

The function void subMatrix(struct matrix m1,...) is technically okay if you don't want to change m1, but this makes an extra copy of m1 which is not efficient. It's better to use void subMatrix(const struct matrix *source,...) instead.

函数void子矩阵(struct matrix m1,…)从技术上来说是可以的,如果你不想改变m1,但是这会增加m1的额外副本,这是无效的。最好使用void子矩阵(const struct matrix *source,…)代替。

You can also use dynamic allocation instead of fixed array of value[10][10]. Example:

您也可以使用动态分配而不是固定的值数组[10][10]。例子:

struct matrix {
    int **data;
    int rows;
    int cols;
};

void create(struct matrix *m, int rows, int cols)
{
    m->rows = rows;
    m->cols = cols;
    m->data = malloc(rows * sizeof(int*));
    for(int r = 0; r < rows; r++)
        m->data[r] = malloc(sizeof(int) * cols);
}

void destroy(struct matrix *m)
{
    for(int i = 0; i < m->rows; i++)
        free(m->data[i]);
    free(m->data);
}

void print(const struct matrix *m)
{
    for(int r = 0; r < m->rows; r++)
    {
        for(int c = 0; c < m->cols; c++)
            printf("%4d", m->data[r][c]);
        printf("\n");
    }
    printf("\n");
}

void change(struct matrix *new, struct matrix *m, int *delete_rows, int *delete_cols)
{
    int rows = 0;
    for(int row = 0; row < m->rows; row++)
        if(!delete_rows[row])
            rows++;
    int cols = 0;
    for(int col = 0; col< m->cols; col++)
        if(!delete_cols[col])
            cols++;
    create(new, rows, cols);

    int next_row = 0;
    for(int row = 0; row < m->rows; row++)
    {
        if(delete_rows[row]) continue;
        int next_col = 0;
        for(int col = 0; col < m->cols; col++)
        {
            if(delete_cols[col]) continue;
            new->data[next_row][next_col] = m->data[row][col];
            next_col++;
        }
        next_row++;
    }
}

int main(void)
{
    struct matrix m;
    create(&m, 10, 10);
    for(int r = 0; r < m.rows; r++)
        for(int c = 0; c < m.rows; c++)
            m.data[r][c] = r * 100 + c;
    print(&m);

    //get delete information
    int delete_rows[10] = { 0 };
    int delete_cols[10] = { 0 };
    delete_rows[0] = 1;//delete row 0
    delete_cols[7] = 1;//delete col 7

    struct matrix new;
    change(&new, &m, delete_rows, delete_cols);
    print(&new);
    destroy(&m);
    destroy(&new);
    return 0;
}