使用链接列表转置稀疏矩阵(遍历问题)

时间:2012-03-29 10:35:01

标签: c++ matrix traversal sparse-matrix

我正试图在c ++中转置稀疏矩阵。我正在努力寻找新的转置矩阵。我想输入从矩阵的第一行到新矩阵的第一列的所有内容。

每一行都有数字应该在的列索引和数字本身。

输入:

colInd num colInd num colInd num

输入:

1 1 2 2 3 3

1 4 2 5 3 6

1 7 2 8 3 9

输出:

1 1 2 4 3 7

1 2 2 5 3 8

1 3 2 6 3 9

如何使列表遍历插入第一个元素的第一列,然后返回顶部插入第二列。如果这是两个很难遵循的道歉。但我想要的帮助就是遍历Transposed矩阵,使其在正确的时间在正确的位置插入一个nz(非零)对象。

这是我的代码

list<singleRow> tran;
//Finshed reading so transpose

for (int i = 0; i < rows.size(); i++){ // Initialize transposed matrix
    singleRow trow;
    tran.push_back(trow);
}

list<singleRow>::const_iterator rit;
list<singleRow>::const_iterator trowit; 
int rowind;
for (rit = rows.begin(), rowind = 1; rit != rows.end(); rit++, rowind++){//rit = row iterator
    singleRow row = *rit;
    singleRow::const_iterator nzit;
    trowit = tran.begin(); //Start at the beginning of the list of rows
    trow = *trowit;
    for (nzit = row.begin(); nzit != row.end(); nzit++){//nzit = non zero iterator
            int col = nzit->getCol();
            double val = nzit->getVal();
            trow.push_back(nz(rowind,val)); //How do I attach this to tran so that it goes in the right place?
            trowit++;
    }
}

2 个答案:

答案 0 :(得分:1)

您对矩阵的表示效率低下:它不使用矩阵稀疏的事实。我之所以这么说是因为它包含了矩阵的所有行,即使它们中的大多数都是零(空),就像通常用稀疏矩阵一样。

您的代表也难以使用。所以我建议首先转换表示(转换为常规的2-D数组),转置矩阵,然后转换回来。

(编辑:) 或者,您可以更改表示,例如,如下所示:

输入:rowInd colInd num

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

输出:

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

代码将是这样的:

struct singleElement {int row, col; double val;};
list<singleElement> matrix_input, matrix_output;

...
// Read input matrix from file or some such

list<singleElement>::const_iterator i;
for (i = matrix_input.begin(); i != matrix_input.end(); ++i)
{
    singleElement e = *i;
    std::swap(e.row, e.col);
    matrix_output.push_back(e);
}

答案 1 :(得分:1)

您对稀疏矩阵的list-of-list表示的选择对于换位来说很差。有时,在考虑算法和数据结构时,最好的做法是将数据结构转换为更适合您算法的数据结构,而不是破坏算法以使用错误的数据结构。

在这种情况下,你可以将你的矩阵读成coordinate list表示,这种表示很容易转置,然后写入你喜欢的任何表示。如果空间是一个挑战,那么您可能需要按块执行此块,在目标表示中逐个分配新列,并在您使用旧表示中取消分配列。