我已经有问题在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。有没有更好的方法来进行这种换位,还是我犯了可以修复的方式犯错误?这让我感到很沮丧,差不多一个星期了,所以任何帮助都非常感谢。如有必要,可以提供进一步的细节。提前谢谢!
答案 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内环的限制。