在C中转置锯齿状阵列?

时间:2014-11-06 20:00:03

标签: c jagged-arrays

我已经有问题在C中转换锯齿状阵列几天了,我真的无法找到解决方案。基本上我们给出了一个大多数为零的矩阵(稀疏矩阵),我们打算将其转换为锯齿状数组。我能做到这一点没问题。备用矩阵是

7 8
0 0 0 5 1 0 0 5
0 0 0 0 0 0 0 0
0 0 0 0 1 2 0 0
1 0 0 0 0 0 0 0
3 0 0 5 0 0 3 0
1 0 0 0 0 3 0 0
0 0 0 0 0 0 0 1

7和8是行和列,我们首先要阅读它们。行全为零的任何点(在本例中为第二行),锯齿状数组意味着为NULL。我们应该使用calloc()为锯齿状数组分配内存,我在这个循环中做了一遍:

for(i=0; i<rows; i++)
{
    for(j=0; j<columns; j++)
    {
        if(matrix[i][j] != 0)
        {
            flag++;
        }
    }
    if(flag > 0)
    {
        jagged[i] = (float *)calloc(flag, sizeof(float));
    }
    else
    {
        jagged[i] = NULL;
    }
    flag = 0;
}   

所以我的锯齿状阵列打印为:

5 1 5
NULL
1 2
1
3 5 3
1 3
1

这是按照它的意图打印出来的,并且工作正常。我们的意思是将锯齿状数组添加到自身中,我在这个循环中做(在函数内部):

    for(i=0; i<rows; i++)
    {
        if(jagged[i]) //if the row exists, continue
        {
            for(j=0; j<columns; j++)
            {
                if(jagged[i][j]) //if the index exists, add it to itself
                {
                    jagged[i][j] += jagged[i][j];
                }
            }
        }
    }

这也可以正常工作,新的锯齿状阵列打印为:

10 2 10
2 4
2
6 10 6
2 6
2

最后一部分是我被困的地方。我现在打算转置上面的数组(行成为列)。我已经尝试了几种方法来解决这个问题。我尝试使用calloc()创建一个新数组,其循环类似于上面的循环,但循环遍历锯齿状数组,并且行和列颠倒。然而,每当我尝试沿着锯齿状数组的列(循环从锯齿状[0] [0]开始,然后下一次迭代处于锯齿状[1] [0])时,我总是会出现分段错误,即使我&#39 ; m检查正在检查的下一行/元素是否为NULL。有没有更好的方法来进行这种换位,还是我犯了可以修复的方式犯错误?这让我感到很沮丧,差不多一个星期了,所以任何帮助都非常感谢。如有必要,可以提供进一步的细节。提前谢谢!

2 个答案:

答案 0 :(得分:2)

显然,原始输入矩阵与您的问题完全无关,而且是一个红色的鲱鱼。我会忽略它,只看你的锯齿状阵列。

为了使锯齿状数组完全有用,你必须知道每行中有多少个数字。否则你永远无法知道是否应该从行中再读一个数字,或者是否会导致段错误。

现在假设你有办法知道每一行中的数字,你已经存储了一个像这样的锯齿状数组m

10 2 10
2 4
2
6 10 6
2 6
2

从一个空的锯齿状数组m_transpose开始。从根本上说,你想做的是, 对于m的每一行,i从0开始向上计数, 从该行x的元素i中读取m; 然后找到其中没有m_transpose个数字的i+1的第一行, 并将x附加到m_transpose的那一行。

如果必须为每一行分配恰当大小的float数组 m_transpose,那么你将不得不两次通过。 在第一遍中,只要m的最长行开始,就会以零数组开头, 然后你按照我已经描述的那样迭代m的每一行,除此之外 而不是将i行中的元素m附加到m_transpose行, 你只需将1添加到小于i+1的整数数组中的第一个元素。 然后,您可以将m_transpose的所有行分配到正确的大小, 在第二遍中,您可以将m的元素复制到m_transpose 如前所述。 (请注意,您需要一个整数数组来跟踪每行的位置 m_transpose你应该&#34;追加&#34;下一个号码。)

就个人而言,除非锯齿状数组的最长行长度和数组中非空行数的乘积非常大(并且远大于非总数) -zero数组的元素),我会分配矩形数据结构 每行中最后一个非零数字后为零。 然后,您可以安全地遍历阵列,而无需一些辅助数据结构 告诉你每行多长时间。

答案 1 :(得分:0)

检查NULL的下一个元素不是解决方案。你必须在它用完之前停止迭代。一旦你读到jagged [i] [j],其中j超出了该数组的界限,你就有了段错误。

如果您在阵列仍然是矩形的情况下首先进行转置然后使其呈锯齿状,那么您可能会有更轻松的时间。

如果不允许这样做,你将不得不跟踪锯齿状数组每行中有多少项,并相应地设置j内环的限制。