【问题标题】:Transfering a 2-dimensional array into a single dimension array将二维数组转换为一维数组
【发布时间】:2016-02-18 06:03:33
【问题描述】:

我正在尝试用 C 语言编写一个程序,将二维数组(特别是矩阵)转换为一维数组。例如,如果我们有一个 L 行 C 列的矩阵,它应该变成单行 newL=L*C。因此,如果矩阵有 3 行 4 列,则新数组的大小为 3*4=12。

矩阵应该变成这样:

1 2
     --> 1 2 3 4
3 4 

我现在面临的问题是如何将矩阵分配给数组,而不需要随机值或重复值。

我关心的代码是这样的:

for(k=1;k<=t;k++)
    {
        for(i=1;i<=l;i++)
        {
            for(j=1;j<=c;j++)
            {
                v[k]=m[i][j];
            }
        }
    }

k,i 和 j 是矩阵(二维数组)和数组的计数器。其中两个; i 和 j 是矩阵的计数器,k 是数组的计数器。请注意,它们中的每一个都从 1 开始并达到它的大小,在这个大小中,我将使用 2 行和 2 列作为矩阵,因此数组的大小为 4(2*2)。

  • l 是数组中的行数。
  • c 是数组中的列数。
  • t 是数组的大小。 t=l*c

执行代码给了我这个作为回报:

1 2
    --> 4 4 4 4
3 4

简单地说,这段代码总是将矩阵的最后一个值提供给数组。因此,如果我将矩阵中的 4 替换为 5,则数组将有 5 5 5 5。

编辑:

这是了解我想要做什么的完整代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int c,i,j,l,k,t;
    printf("Donner le nombres des lignes: ");
    scanf("%d",&l);
    printf("Donner le nombres des colonnes: ");
    scanf("%d",&c);
    int m[l][c];
    t=l*c;
    int v[t];
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("Donner m[%d][%d]: ",i+1,j+1);
            scanf("%d",&m[i][j]);
        }
    }
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("%d\t",m[i][j]);
        }
        printf("\n");
    }
    printf("\n\n\n\n");
    for(k=1;k<=t;k++)
    {
        for(i=1;i<=l;i++)
        {
            for(j=1;j<=c;j++)
            {
                v[k]=m[i][j];
            }
        }
    }
    for(k=0;k<t;k++)
    {
        printf("%d\t",v[k]);
    }
    system("pause");
}

谢谢大家的帮助,我找到了正确的方法。

【问题讨论】:

  • 不要使用容易与数字混淆的字母!在这里,我假设您的意思是字母 l(小写“ell”)。
  • @Olaf 这是一个坏习惯。你昨天告诉我的,我现在还在用。对不起。是的,我的意思是小写 L 和 l。
  • 尽快摆脱那个霍比特人 - 嗯习惯。你保存的时间越长,它就会变得越难。也摆脱来自1 的索引数组。大多数编程语言使用从零开始的数组索引。其他任何事情都只会混淆并可能阻止编译器优化程序。
  • 不要编辑说你找到了正确的方法!将其中一个答案标记为正确,或者如果您找到了更好的方法,请添加您自己的答案!
  • @Ben 感谢您的提示,已完成。

标签: c arrays matrix multidimensional-array dimensions


【解决方案1】:

您提到您的问题是“我如何修复代码?”我想很多人都给了你正确的答案。这是您的代码以及更正后的代码。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int c,i,j,l,k,t;
    printf("Donner le nombres des lignes: ");
    scanf("%d",&l);
    printf("Donner le nombres des colonnes: ");
    scanf("%d",&c);
    int m[l][c];
    t=l*c;
    int v[t];
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("Donner m[%d][%d]: ",i+1,j+1);
            scanf("%d",&m[i][j]);
        }
    }
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            printf("%d\t",m[i][j]);
        }
        printf("\n");
    }
    printf("\n\n\n\n");

    /* corrected code below */
    k = 0;
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
        {
            v[k]=m[i][j];
            k++;
        }
    }
    /* corrected code above */

    for(k=0;k<t;k++)
    {
        printf("%d\t",v[k]);
    }
    system("pause");
}

【讨论】:

  • 是的,我回复了一个叫 Ben 的人说它有效,忘记编辑了。对不起。
【解决方案2】:

如果您只想将矩阵元素作为一维数组访问,您可以声明一个int 指针v

int m[3][4];
int *v = (int*)m;
// then access for example m[1][1] as v[5]

或者,要实际复制数组,请使用双 for(如其他答案),单 for 如下所示

int vv[12];
for(i = 0; i < 12; i++)
    vv[i] = m[i/4][i%4];

或者直接使用memcpy:

memcpy(vv, m, 12*sizeof(int));

【讨论】:

【解决方案3】:

如果我们有一个像这样的多维数组:

int nums[3][3];

我们有:

int all[9];

我们有:

int a, b;

我们将像这样引用每个数字:

nums[a][b];

现在想想 a 和 b 的实际值是什么:

for (a = 0; a < 3; a++) {
   for (b = 0; b < 3; b++)
      all[((a * 3) + b)] = nums[a][b];
}

只要将 a 乘以它要迭代的元素数,这将起作用:

int nums[5][5];
int all[25];

int a, b;

for (a = 0; a < 5; a++) {
    for (b = 0; b < 5; b++)
        all[((a * 5) + b)] = nums[a][b];
}

【讨论】:

    【解决方案4】:

    这个:

    for(k=1;k<=t;k++)
       for(i=1;i<=l;i++)
          for(j=1;j<=c;j++)
              v[k]=m[i][j];
    

    没有按照你的想法做。想想当你第一次循环遍历j 部分时,你将一直设置 v 的所有 0th 元素,最后你设置的最后一个值将保持不变(即,恰好位于 1, 1 位置的那个值是4)。然后将k 递增到1 并再次重复,得到所有4's。你想要这个:

     for(i = 0; i < l; i++)
         for(j = 0; j < c; j++)
             v[i*l+j] = m[i][j]; // i*l + j gives you the equivelent position in a 1D vector. 
    

    确保您的v 向量大小合适,即。 int v[l*c];。还要记住在c 中使用了零索引。如果您确实需要基于 1 的索引(您不需要...),请执行以下操作:

    int k = 1;
      for(i = 1; i <= l; i++)
         for(j = 1; j <= c; j++)
             v[k++]=m[i][j];
    

    但请记住,这将对这个向量 Gross 进行任何进一步的操作。所以不要这样做....

    【讨论】:

    • 您的代码在赋值行中使用了k,但从未声明它。
    • 但是我仍然需要一个 FOR 来让数组填充每一帧。
    • @Amine 我不明白你的意思。
    • i 和 j 将以 i 开头,意味着 L 等于 2。新数组将首先填充帧 1*2+1,然后是 2*2+2,依此类推.. 它不起作用.
    • 据我所知,它们是相同的,您只需更改循环停止的位置即可。如果你从 0 开始,那么 i 在 L (i
    【解决方案5】:

    只要新数组的大小正确,就应该可以使用以下方法:

    k=0;
    for(i=0;i<l;i++){
        for(j=0;j<c;j++){
            v[k]=m[i][j];
            k++;
        }
    }
    

    本质上,您正在遍历矩阵(您的行和列 - 正如您所说的那样),同时增加新数组中您希望放置该值的位置 (k)。

    【讨论】:

      【解决方案6】:
      1. 你不需要外循环
      2. 数组索引在 C 中从零开始

      因此,我们有:

          for(k = 0, i = 0; i < o; i++)
          {
              for(j = 0; j < p; j++)
              {
                  v[k++] = m[i][j];
              }
          }
      

      其中op - 矩阵的维度m

      【讨论】: