【问题标题】:Matrix with variables in CC 中带有变量的矩阵
【发布时间】:2012-11-08 01:39:44
【问题描述】:

我将编写伪代码以使我的问题更清楚。请记住,此代码将在 C 中完成。

想象一下,我有一个包含任意数量数字的数组。第一个数字告诉我我们正在处理的数组有多大。例如,如果我的第一个数字是 3,这意味着我有两个 3x3 矩阵。所以我创建了两个多维数组:

matrix1[3][3]
matrix2[3][3]

我遇到的困难是将所有数字分配给矩阵的算术/编码,我很难想象它是如何完成的。

假设一个测试数组包含 [2,1,2,3,4,5,6,7,8]

我的程序现在应该有两个矩阵:

1 2    5 6
3 4    7 8

我需要几个嵌套循环吗?任何帮助,将不胜感激。

【问题讨论】:

  • 您要查找的关键字是模数和整数除法:)
  • 是的,它们是方阵。
  • 假设您将线性数组中的所有数据都放入其中,您根本不需要 任何 循环(或分配)。

标签: c arrays multidimensional-array matrix


【解决方案1】:

目前我得到的唯一想法是使用两个for loops。或者您可以创建一个函数并在每次需要时调用它(但不要忘记使用k 作为第二个参数)。

int i, j, k;

/* We start in the 2nd element of the array that's why k = 1. */
k = 1;

/* Now we fill the array1 copying 1 by 1 the elements of the "test array" until
   we fill it. Then we do the same with the array2. */
for( i = 0; i < test[ 0 ]; i++ ){
   for( j = 0; j < test[ 0 ]; j++ ){
       array1[ i ][ j ] = test[ k ]
       k++;
   }
}

for( i = 0; i < test[ 0 ]; i++ ){
   for( j = 0; j < test[ 0 ]; j++ ){
       array2[ i ][ j ] = test[ k ]
       k++;
   }
}

【讨论】:

  • 哦,这是个好主意,方向对了,让我测试一下,看看它是否有效。
【解决方案2】:

C 中多维数组的问题是你需要提前(在编译时)知道 n-1 的维度大小,当用作函数参数时它们也是一个拖累。

有几种替代方法:

  1. 创建一个数组数组。即分配一个数组指针数组,然后将数组分配给这些指针。

    type **array = malloc(sizeof(type * ) * );
    数组[0] = malloc(sizeof(type) * );
    ...

  2. 分配具有所有相乘维度大小的单维数组。即

    type *array = malloc(sizeof(type) * * );

在您的情况下,第二个可能更合适。比如:

matrix1 = malloc(sizeof(type)*<firstnumread>*<firstnumread>);  
matrix2 = malloc(sizeof(type)*<firstnumread>*<firstnumread>);

然后你可以像这样赋值:

matrix1[column*<firstnumread> + row] = <value>;

是的,有 2 个 for 循环。

【讨论】:

    【解决方案3】:

    二维数组存储在矩阵中连续的一系列行中。所以你甚至不需要分配新的内存就可以使用你的原始数组。无论如何,您也可以创建 2 个新的独立阵列。 您可以像这样创建一个函数,以获取正确的矩阵编号。

    int getNumber(int array[], int arraynumber, int index_x, int index_y)
    {
       return array[(((array[0]*index_x)+index_y)+1)+((array[0]*array[0])*arraynumber)];
    }
    

    arraynumber 变量对于第一个矩阵是 0,对于第二个矩阵是 1。这个功能只有在所有参数都正确的情况下才起作用,所以没有错误检测。
    使用此函数,您可以轻松循环并创建 2 个新数组:

    int i,k;
    for (i=0; i<array[0]; i++)
    {
       for (k=0; k<array[0]; k++)
       {
          newarray1[i][k] = getNumber(array, 0, i,k);
          newarray2[i][k] = getNumber(array, 1, i,k);
       }
    }
    

    【讨论】:

      【解决方案4】:

      这是一个在单个循环中工作的东西;没有巢也没有重复。我不知道它是否会胜过其他答案,但我只是想给你一个不同的答案^_^

      我没有测试过这段代码,但看起来算法的逻辑是有效的——这就是重点,对吧?如果有任何错误,请告诉我......

      int c=0, x=0, y=0, size=test[0], length=sizeof(test);
      
      for(i=1; i<length; i++) {
          if((c-size)<0) {
              matrix1[x][y] = test[i];
          } else {
              matrix2[x][y] = test[i];
          }
          ++y;
          if(y%size == 0) {
              ++c;
              y = 0;
              x = (c-size)<0 ? ++x : 0;
          }
      }
      

      【讨论】:

        【解决方案5】:

        您的数据以行优先顺序显示。在读取您的整数数组并验证内容后(即 dim=4 表示后面有 32 个值,dim=2 表示后面有 8 个值等)我不确定您为什么要分配或循环 anything.

        您可以使用您的物理测试[]数据作为矩阵

        int dim = test[0];
        int (*mat1)[dim] = (int (*)[dim])(test+1);
        int (*mat2)[dim] = (int (*)[dim])(test+1 + dim*dim);
        

        C99 在实现级别支持变量数组声明(即编译器可以支持标准定义的特性,但没有;参见 C99 标准的 6.7.6.2更多信息)。如果您的工具链支持它,那么预定义的宏,__STDC_NO_VLA__ 必须被定义并且可以在编译时进行测试(参见章节C99 标准的 6.10.8.3-1)。话虽如此,我在过去十多年中使用过的每一个符合 C99 的编译器支持它,所以如果你的不支持,请在下面的评论中告诉我们。

        如果是这样,请注意上面mat1mat2 的声明中使用'dim')。这是我喜欢的 C++ 所没有的少数几个特性之一。所以和你带来的那个跳舞吧。

        最后,假设您的编译器符合 C99 并支持 VLA(__STDC_NO_VLA__ 未定义),作为额外的超级特殊奖励,它几乎可以保证是最快的算法得到你的两个矩阵,因为没有算法。您读取一个数组元素,然后分配两个指针。 O(3) 很难被击败。

        示例

        #include <stdlib.h>
        #include <stdio.h>
        
        // main loader.
        int main(int argc, char *argv[])
        {
            int test[] = {2,1,2,3,4,5,6,7,8};
            int dim = test[0];
            int (*mat1)[dim] = (int (*)[dim])(test+1);
            int (*mat2)[dim] = (int (*)[dim])(test+1 + dim*dim);
        
            // proof stuff is where it should be.
            int i=0,j=0;
            for (i=0;i<dim;i++)
            {
                for (j=0;j<dim;printf("%d ", mat1[i][j++]));
                printf ("   ");
                for (j=0;j<dim;printf("%d ", mat2[i][j++]));
                printf("\n");
            }
        
            return EXIT_SUCCESS;
        }
        

        输出

        1 2    5 6 
        3 4    7 8 
        

        使用 3x3 数据集的类似测试:

        int test[] = {3,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1};
        

        输出

        1 2 3    9 8 7 
        4 5 6    6 5 4 
        7 8 9    3 2 1 
        

        最后,一个 4x4 数据集:

        int test[] = {4,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};
        

        输出

        1 2 3 4    8 7 6 5 
        5 6 7 8    4 3 2 1 
        1 2 3 4    8 7 6 5 
        5 6 7 8    4 3 2 1 
        

        【讨论】:

          猜你喜欢
          • 2021-11-17
          • 1970-01-01
          • 2012-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多