【问题标题】:Structure to hold uneven dynamic matrix? [closed]保持不均匀动态矩阵的结构? [关闭]
【发布时间】:2014-04-16 18:34:25
【问题描述】:

我想创建一个矩阵结构,其行数不均匀,如下所示:

[0] [0] 
[0] [0] [0] 
[0] [0] [0] [0] 
[0] [0] [0] [0] [0] 
[0] [0] [0] [0] 

因此,我想在某处存储它的列长度以及每行的宽度。我的实现是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
    size_t size;
    int *data;
} dyn_row;

typedef struct {
    size_t size;
    dyn_row *row;
} dyn_matrix;

int main(void) {

    int i, j;
    dyn_matrix matrix;

    srand(time(NULL));
    // Allocate
    matrix.size = 5;
    matrix.row = malloc(matrix.size * sizeof(dyn_row));
    for (i=0; i<matrix.size; i++) {
        matrix.row[i].size = rand()%(i+1)+2;
        matrix.row[i].data = malloc((matrix.row[i].size) * sizeof(int));
    }
    // Initialize
    for (i=0; i<matrix.size; i++) {
        for (j=0; j<matrix.row[i].size; j++) {
            matrix.row[i].data[j] = 0;
        }
    }
    // Print values & free
    for (i=0; i<matrix.size; i++) {
        for (j=0; j<matrix.row[i].size; j++) {
            printf("[%d] ", matrix.row[i].data[j]);
        }
        printf("\n");
        free(matrix.row[i].data);
    }
    free(matrix.row);

    return 0;
}

这是一个好的解决方案吗?解决这个问题的最佳实现是什么?另外,用“void *data”代替“int *data”是否是一种好习惯,这样矩阵可以保存任何类型的数据?

【问题讨论】:

  • 你所拥有的是一个合理的解决方案。如果您只关心int 的数组,则使用int * 比使用void * 更好。如果您知道要存储其他类型,那么void * 解决方案可以让某些事情起作用,但取消引用数据将是一个涉及强制转换的繁琐过程。一般来说,您最好使用准确的具体类型,而不是尝试void *。此外,对单元格 (i,j) 的随机访问需要检查。
  • 询问一个可行的解决方案是否是一个好的解决方案可能应该发布在Code Review instead of 这里(如果你还没有测试过,你应该在发布之前这样做)。 “最优”是哪方面的?空间?时间?代码的可读性? voidpointers 有这种将编译时错误转化为运行时错误的习惯,这是一件坏事,并且会影响代码的可读性(所以应该尽可能避免)。
  • 这个问题似乎离题了,因为它是一个代码审查并且属于codereview.stackexchange.com而不是SO。

标签: c data-structures matrix struct


【解决方案1】:

如果您知道您要实现的目标被称为“锯齿状数组”,您可能会发现更多示例;尽管您也会发现其他语言更好地支持这种数据结构。

分配数据是微不足道的部分,但您最好定义单独的函数来分配和访问数组以安全地包装这些操作(访问边界检查、内存管理等)。例如,您可以定义:

typedef dyn_matrix* tJaggedArray ;

// Create n rows of initially zero length
tJaggedArray jaggedCreate( int rows ) ; 

// Set the length and allocate a row in array
tJaggedArray jaggedAllocRow( tJaggedArray array, int row, int length ) ;

// Get an array element, return true if element exists, else false
bool jaggedGet( tJaggedArray array, int row, int col, int* value ) ;

// Set an array element, return true if element exists, else false
bool jaggedSet( tJaggedArray array, int row, int col, int value ) ;

// Clean up array resources
void jaggedDestroy( tJaggedArray array ) ;

在 C++ 中,您当然可以将其包装在一个类中,这样您就不必将数组指针传递给每个函数,并且您可以使用模板来支持不同类型的数组,并使用运算符重载来使数组访问看起来像内置数组访问。在 C# 中,边界检查是语言内置的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 2013-02-05
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    相关资源
    最近更新 更多