我正在尝试从3D动态数组的每个切片中删除前20列。我猜想尝试为2D动态数组编写函数可以解决我将迭代3D数组的每个级别的问题。我在stackoverflow中得到了一个例子,我正在努力工作。
但问题是函数无法删除整列。相反,它只删除一个元素。谁能让我知道如何从2D动态数组中删除整列?
void removeColumn(int** matrix, int col){
MATRIX_WIDTH--;
for(int i=0;i<MATRIX_HEIGHT; i++) {
while(col<MATRIX_WIDTH)
{
//move data to the left
matrix[i][col]=matrix[i][col+1];
col++;
} matrix[i] = realloc(matrix[i], sizeof(double)*MATRIX_WIDHT); }
我的预期输出就像 样本输入:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
示例输出:
1 3 4
5 7 8
9 11 12
13 15 16
更新:这是使用@frslm建议后完全删除列的代码 但矩阵没有调整大小。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int** fill(size_t rows, size_t cols, int input[][cols])
{
int i,j,count=1;
int** result;
result = malloc((rows)*sizeof(int*));
for(i=0;i<rows;i++)
{
result[i]=malloc(cols*sizeof(int));
for(j=0;j<cols;j++)
{
result[i][j]=count++;
}
}
return result;
}
void printArray2D(size_t rows, size_t cols,int** input)
{
int i,j;
for(i=0;i<rows;i++)
{
for(j=0;j<cols;j++)
{
printf(" %4d",input[i][j]);
}
printf("\n");
}
}
void removeColumn(int** matrix, int col2del , int rows, int cols){
int MATRIX_WIDTH = cols;
int MATRIX_HEIGHT = rows;
MATRIX_WIDTH--;
for(int i=0;i<MATRIX_HEIGHT; i++) {
int curr_col = col2del;
while(curr_col<MATRIX_WIDTH)
{
//move data to the left
matrix[i][curr_col]=matrix[i][curr_col+1];
curr_col++;
}
//matrix[i] = realloc(matrix[i], sizeof(int)*MATRIX_WIDTH); // <- int, not double
matrix[i] = realloc(matrix[i], sizeof (matrix[i][0])*MATRIX_WIDTH);
}
}
int main()
{
int arRow,arCol;
arRow =8;
arCol = 9;
int ar[arRow][arCol];
int **filled;
filled = fill(arRow, arCol, ar);
printArray2D(arRow,arCol,filled);
removeColumn(filled, 3,arRow,arCol);
printf("After 3rd Column Delete.......\n");
printArray2D(arRow,arCol,filled);
return(0);
}
输出:最后一列重复
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27
28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54
55 56 57 58 59 60 61 62 63
64 65 66 67 68 69 70 71 72
After 3rd Column Delete.......
1 2 3 5 6 7 8 9 9
10 11 12 14 15 16 17 18 18
19 20 21 23 24 25 26 27 27
28 29 30 32 33 34 35 36 36
37 38 39 41 42 43 44 45 45
46 47 48 50 51 52 53 54 54
55 56 57 59 60 61 62 63 63
64 65 66 68 69 70 71 72 72
答案 0 :(得分:2)
您递增col
直到它到达第一行的末尾,但您从未为后续行重置它,这就是为什么您最终只删除第一行的列。
确保在每次迭代开始时重置col
:
void removeColumn(int** matrix, int col){
MATRIX_WIDTH--;
for(int i=0;i<MATRIX_HEIGHT; i++) {
int curr_col = col; // <- use a temporary `col` variable for each row
while(curr_col<MATRIX_WIDTH)
{
//move data to the left
matrix[i][curr_col]=matrix[i][curr_col+1];
curr_col++;
}
matrix[i] = realloc(matrix[i], sizeof(int)*MATRIX_WIDTH); // <- int, not double
}
}
修改(响应OP编辑):
确保removeColumn()
在调整矩阵大小后更新列数(cols
);一种方法是使用指针:int *cols
作为参数而不是int cols
(在调用此函数时不要忘记传入地址&arCol
) 。另外,我建议摆脱不必要的MATRIX_HEIGHT
变量:
void removeColumn(int** matrix, int col2del, int rows, int *cols){
int MATRIX_WIDTH = --(*cols);
for(int i=0;i<rows; i++) {
int curr_col = col2del;
while(curr_col<MATRIX_WIDTH)
{
//move data to the left
matrix[i][curr_col]=matrix[i][curr_col+1];
curr_col++;
}
matrix[i] = realloc(matrix[i], sizeof(matrix[i][0])*MATRIX_WIDTH);
}
}
答案 1 :(得分:1)
如果您传递宽度和高度,并更新宽度,则会更容易:
void removeColumn(int** matrix, int col, int* width, int height)
{
int j, i;
for (j = 0; j < height; ++j) {
if (col == *width-1) {
continue;
}
for (i = col; i < *width; ++i) {
matrix[j][i] = matrix[j][i+1];
}
// this is not necessary, but I'm adding as requested
matrix[j] = realloc(
matrix[j],
sizeof(int) * (*width - 1)
);
}
--(*width);
}
您还可以避免动态内存分配,避免内存碎片整理:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int max_width, max_height;
int width, height;
int* values;
} matrix;
void removeColumn(matrix* matrix, int col)
{
int y, i;
for (y = 0; y < matrix->height; ++y) {
if (col == matrix->width-1) {
continue;
}
i = col + matrix->height * y;
while (i < matrix->width) {
matrix->values[i] = matrix->values[++i];
}
}
--matrix->width;
}
void printMatrix(matrix* matrix)
{
int y, x;
for (y = 0; y < matrix->height; ++y) {
for (x = 0; x < matrix->width; ++x) {
printf("%d ", matrix->values[x + matrix->width * y]);
}
printf("\n");
}
}
int main ()
{
int y, x = 0;
matrix matrix;
matrix.max_width = 4;
matrix.max_height = 4;
matrix.width = 4;
matrix.height = 4;
int values[4][4];
matrix.values = &values;
for (y = 0; y < matrix.height; ++y) {
for (x = 0; x < matrix.width; ++x) {
int i = x + matrix.width * y;
matrix.values[i] = i % 10;
}
}
printMatrix(&matrix);
removeColumn(&matrix, 1);
printf("===\n");
printMatrix(&matrix);
}
使用:https://www.tutorialspoint.com/compile_c_online.php
进行测试<强> ADDED 强>
但是当数组大小太大时,我们还有其他选择吗? 但使用动态数组
如果要制作可调整大小的数组,则在分配数组时可以使用单个malloc
,并在realloc
大于width
时使用max_width
或height
将大于max_height
。
尽管如此,我认为我们应该尽量避免使用malloc
或realloc
进行大量动态分配,因为它们会变慢(尽管大部分时间你都没有注意到) ,它们可以对内存进行严格的碎片整理,并且它的方式会产生大量不必要的缓存未命中。
如果你不知道你需要多次调整阵列的大小,你也应该增加它们的数量,例如,指数增长。这通常是(正确地)实现了哈希和动态数组。
例如,您可能会发现几个没有动态内存的JSON,XML和HTML C库以避免其陷阱,并且在许多专业视频游戏中,可能会使用巨大的malloc
来避免大量的这些并且简单数组被大量使用。
https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/
http://gamesfromwithin.com/start-pre-allocating-and-stop-worrying
当然,您可以使用动态内存,但要更好地理解其陷阱以获得更好的决策。