插入稀疏矩阵时出现问题
Problem when inserting in a Sparse Matrix
我必须使用 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
- returns 在 (i,j)
上找到的值
我想用下一种方式测试我的代码:
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);
else
assert(m.element(i, j) == NULL_TELEM);
令我惊讶的是 m.element(4,j) 对于范围 (0,8) 中的 j 将为 0,对于 j=9 仅为 3。
这是我对 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[1000];
this->values_capacity = 1;
this->values_size = 0;
this->lines = new int[nrLines + 1];
this->columns = new TElem[1000];
this->columns_capacity = 1;
this->columns_size = 0;
for (int i = 0; i <= nrLines; i++)
this->lines[i] = NULL_TELEM;
}
这是"modify"方法:
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 + 1; i <= this->nr_lines; i++)
this->lines[i]++;
}
有人可以帮助我吗?我不明白为什么会这样,这些天我真的需要完成这个实现。看到这些位置的值为 0 很奇怪。
所以下一个测试以下一种方式开始,我遇到了内存访问冲突:
Matrix m(200, 300);
for (int i = m.nrLines() / 2; i < m.nrLines(); i++) {
for (int j = 0; j <= m.nrColumns() / 2; j++)
{
int v1 = j;
int v2 = m.nrColumns() - v1 - 1;
if (i % 2 == 0 && v1 % 2 == 0)
m.modify(i, v1, i * v1);
else
if (v1 % 3 == 0)
m.modify(i, v1, i + v1);
if (i % 2 == 0 && v2 % 2 == 0)
m.modify(i, v2, i * v2);
else
if (v2 % 3 == 0)
m.modify(i, v2, i + v2);
}
方法"modify" at currCol = this->column[pos];
中抛出错误
如果我查看调试器,它看起来 like:i=168, lines[i]=-842150451, lines[i+1]=10180,pos=-842150451.
有人知道为什么它看起来像这样吗?
您的代码有两个小错误。
当你试图在modify
中找到插入位置时,你遍历了行中的非空元素:
int currCol = 0;
for (; pos < this->lines[i + 1]; i++) {
currCol = this->columns[pos];
if (currCol >= j)
break;
}
在这里,您必须在每次迭代中更新 pos++
而不是 i++
。
第二个错误发生在你向第0列插入元素时。currCol
将为零,但你添加新元素的条件是
if (currCol != j) {
if (!(e == 0))
add(pos, i, j, e);
}
但是 j
也为零,因此不会插入任何内容。您可以通过从不存在的列开始来解决此问题:
int currCol = -1;
我必须使用 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
- returns 在 (i,j)
我想用下一种方式测试我的代码:
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);
else
assert(m.element(i, j) == NULL_TELEM);
令我惊讶的是 m.element(4,j) 对于范围 (0,8) 中的 j 将为 0,对于 j=9 仅为 3。
这是我对 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[1000];
this->values_capacity = 1;
this->values_size = 0;
this->lines = new int[nrLines + 1];
this->columns = new TElem[1000];
this->columns_capacity = 1;
this->columns_size = 0;
for (int i = 0; i <= nrLines; i++)
this->lines[i] = NULL_TELEM;
}
这是"modify"方法:
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 + 1; i <= this->nr_lines; i++)
this->lines[i]++;
}
有人可以帮助我吗?我不明白为什么会这样,这些天我真的需要完成这个实现。看到这些位置的值为 0 很奇怪。
所以下一个测试以下一种方式开始,我遇到了内存访问冲突:
Matrix m(200, 300);
for (int i = m.nrLines() / 2; i < m.nrLines(); i++) {
for (int j = 0; j <= m.nrColumns() / 2; j++)
{
int v1 = j;
int v2 = m.nrColumns() - v1 - 1;
if (i % 2 == 0 && v1 % 2 == 0)
m.modify(i, v1, i * v1);
else
if (v1 % 3 == 0)
m.modify(i, v1, i + v1);
if (i % 2 == 0 && v2 % 2 == 0)
m.modify(i, v2, i * v2);
else
if (v2 % 3 == 0)
m.modify(i, v2, i + v2);
}
方法"modify" at currCol = this->column[pos];
中抛出错误如果我查看调试器,它看起来 like:i=168, lines[i]=-842150451, lines[i+1]=10180,pos=-842150451.
有人知道为什么它看起来像这样吗?
您的代码有两个小错误。
当你试图在modify
中找到插入位置时,你遍历了行中的非空元素:
int currCol = 0;
for (; pos < this->lines[i + 1]; i++) {
currCol = this->columns[pos];
if (currCol >= j)
break;
}
在这里,您必须在每次迭代中更新 pos++
而不是 i++
。
第二个错误发生在你向第0列插入元素时。currCol
将为零,但你添加新元素的条件是
if (currCol != j) {
if (!(e == 0))
add(pos, i, j, e);
}
但是 j
也为零,因此不会插入任何内容。您可以通过从不存在的列开始来解决此问题:
int currCol = -1;