【问题标题】:Sparse matrix compressed on rows in C++在 C++ 中的行上压缩的稀疏矩阵
【发布时间】:2020-07-01 20:28:29
【问题描述】:

我必须使用 3 个动态数组(索引从 0 开始)在 C++ 中实现 CSR 矩阵数据结构,但我遇到了困难。所以我必须实现2个功能:

1) modify(int i, int j, TElem e) - 将 (i,j) 的值修改为 e 或添加 if(如果它不存在)或如果 e 为 null 则删除它。

2) element(int i, int j) const - 返回在 (i,j) 上找到的值

我想用下一种方式测试我的代码:

矩阵 m(4,4); m.print();它将打印:

行数:0 0 0 0 0

列:

价值观:

(这很好)

现在如果我想修改:m.modify(1,1,5); //元素(1,1)将被设置为5

m.print() 的输出;将是:

行数:0 1 1 1 1

列数:1

值:5(这也很好)

现在如果我想打印 m.element(1, 1) 它将返回 0 而 m.element(0, 1) 将返回 5。

这是我对 element(int i, int j) 的实现:

    int currCol;
    for (int pos = this->lines[i]; pos < this->lines[i+1]; pos++) {
        currCol = this->columns[pos];
        if (currCol == j)
            return this->values[pos];
        else if (currCol > j)
            break;
    }
    return NULL_TELEM;

构造函数如下所示:

Matrix::Matrix(int nrLines, int nrCols) {
    if (nrLines <= 0 || nrCols <= 0)
        throw exception();
    this->nr_lines = nrLines;
    this->nr_columns = nrCols;
    this->values = new TElem[100];
    this->values_capacity = 1;
    this->values_size = 0; 
    this->lines = new int[nrLines + 1];
    this->columns = new TElem[100];
    this->columns_capacity = 1;
    this->columns_size = 0; 
    for (int i = 0; i <= nrLines; i++)
        this->lines[i] = NULL_TELEM;
}

这是“修改”方法:

TElem Matrix::modify(int i, int j, TElem e) {
    if (i < 0 || j < 0 || i >= this->nr_lines || j >= nr_columns)
        throw exception();
    int pos = this->lines[i];
    int currCol = 0;
    for (; pos < this->lines[i + 1]; i++) {
        currCol = this->columns[pos];
        if (currCol >= j)
            break;
    }
    if (currCol != j) {
        if (!(e == 0)) 
            add(pos, i, j, e);
    }
    else if (e == 0)
        remove(pos, i);
    else
        this->values[pos] = e;
    return NULL_TELEM;
}

这是插入方法:

void Matrix::add(int index, int line, int column, TElem value)
{
    this->columns_size++;
    this->values_size++;
    for (int i = this->columns_size; i >= index + 1; i--) {
        this->columns[i] = this->columns[i - 1];
        this->values[i] = this->values[i - 1];
    }
    this->columns[index] = column;
    this->values[index] = value;
    for (int i = line; i <= this->nr_lines; i++) //changed to i = line + 1;
        this->lines[i]++;
}

有人可以帮帮我吗?我不知道为什么会发生这种情况,我真的需要这些天完成这个实现。

只是无法通过下一个测试。如果我想打印我有 (4,0)=0 (4,1)=0 ... (4,8)=0 和 (4,9)=3 的元素。现在看起来很奇怪,为什么会这样。

void testModify() {
    cout << "Test modify" << endl;
    Matrix m(10, 10);
    for (int j = 0; j < m.nrColumns(); j++)
        m.modify(4, j, 3);
    for (int i = 0; i < m.nrLines(); i++)
        for (int j = 0; j < m.nrColumns(); j++)
            if (i == 4)
                assert(m.element(i, j) == 3);
                //cout << i << " " << j << ":" << m.element(i, j)<<'\n';
            else
                assert(m.element(i, j) == NULL_TELEM);
}

【问题讨论】:

  • 我们需要查看更多细节。 Matrix 类的定义是什么,尤其是 modify 函数。 Editminimal reproducible example 添加足够详细信息的问题(最低限度意味着您可以省略与问题无关的课程详细信息)。
  • 我添加了构造函数和插入元素的函数。这些似乎工作正常。但我不明白为什么“元素”方法没有返回好的值。

标签: c++ algorithm matrix data-structures sparse-matrix


【解决方案1】:

当您使用空矩阵(全为零)调用modify(1, 1, 5) 时,会导致调用add(0, 1, 1, 5)。将columns_sizevalues_size 递增(都为1),for 循环体将不会执行,您将columns[0] 更新为1values[0]5,然后递增所有lines值从元素 lines[1] 开始,将它们全部设置为 1(lines[0] 仍将是 0)。但是lines[1]应该表示我们刚刚添加的元素,所以应该是0,因为值是使用columns[0]找到的。

add 末尾的 for 循环应该从元素 line + 1 开始。

【讨论】:

  • 非常感谢!现在有效,这是有道理的。但是现在我有另一个问题......它只是没有通过这个测试:(我把它放在帖子的末尾)
  • 所以 m.element() 只看到 (4,9)=3 而其他都是 0 这是不正确的。
  • 先生,您知道为什么它没有通过测试吗?
猜你喜欢
  • 2015-12-05
  • 1970-01-01
  • 2019-03-12
  • 2016-10-04
  • 2023-03-25
  • 2015-12-30
  • 2017-07-07
  • 2014-09-18
  • 2011-10-02
相关资源
最近更新 更多