【发布时间】:2018-12-07 00:26:07
【问题描述】:
问题:我用相同的解决方案重载了运算符* 和*=,尽管使用运算符*= 似乎并没有改变矩阵的内容,也许我错误地声明了运算符重载方法。
同时操作符*工作正常,实际上是乘以矩阵,我事先查过了。
输出:
3 4 -5
8 0 7
8 9 -4
8 7 7
-6 0 6
2 2 9
3 4 -5
8 0 7
8 9 -4
这是代码本身:
struct WrappedMatrix{
int n;
int ** Matrix;
};
struct WrappedVector{
int n;
int * Vector;
};
WrappedVector linearizedMatrix(WrappedMatrix matrix){
WrappedVector vector;
vector.n = matrix.n * matrix.n;
vector.Vector = new int[vector.n];
for(int i = 0; i < matrix.n; i++){
for(int j = 0; j < matrix.n; j++){
int k = j + (int) (i*sqrt(vector.n));
vector.Vector[k] = matrix.Matrix[i][j];
}
}
return vector;
}
WrappedMatrix normalMatrix(WrappedVector vector){
WrappedMatrix matrix;
matrix.n = sqrt(vector.n);
matrix.Matrix = new int * [matrix.n];
for(int i = 0; i < matrix.n; i++){
matrix.Matrix[i] = new int[matrix.n];
for(int j = 0; j < matrix.n; j++){
int k = j + (int) (i*sqrt(vector.n));
matrix.Matrix[i][j] = vector.Vector[k];
}
}
return matrix;
}
WrappedVector operator*(const WrappedVector& vector1, const WrappedVector& vector2) {
if(vector1.n != vector2.n) {
cout << "Матриці різних розмірів!" << endl;
return vector1;
}
WrappedMatrix matrix1 = normalMatrix(vector1);
WrappedMatrix matrix2 = normalMatrix(vector2);
WrappedMatrix result;
result.n = matrix1.n;
result.Matrix = new int * [result.n];
for(int i = 0; i < result.n; i++){
result.Matrix[i] = new int[result.n];
}
for(int i = 0; i < result.n; i++){
for(int j = 0; j < result.n; j++){
for(int k = 0; k < result.n; k++){
int p1 = matrix1.Matrix[i][k];
int p2 = matrix2.Matrix[k][j];
result.Matrix[i][j] += p1 * p2;
}
}
}
WrappedVector resultV = linearizedMatrix(result);
return resultV;
}
//?
WrappedVector operator*=(const WrappedVector& vector1, const WrappedVector& vector2) {
if(vector1.n != vector2.n) {
cout << "Матриці різних розмірів!" << endl;
return vector1;
}
WrappedMatrix matrix1 = normalMatrix(vector1);
WrappedMatrix matrix2 = normalMatrix(vector2);
WrappedMatrix result;
result.n = matrix1.n;
result.Matrix = new int * [result.n];
for(int i = 0; i < result.n; i++){
result.Matrix[i] = new int[result.n];
}
for(int i = 0; i < result.n; i++){
for(int j = 0; j < result.n; j++){
for(int k = 0; k < result.n; k++){
int p1 = matrix1.Matrix[i][k];
int p2 = matrix2.Matrix[k][j];
result.Matrix[i][j] += p1 * p2;
}
}
}
WrappedVector resultV = linearizedMatrix(result);
return resultV;
}
int main() {
WrappedMatrix matrix;
matrix.n = 3;
matrix.Matrix = new int * [matrix.n];
matrix.Matrix[0] = new int[matrix.n];
matrix.Matrix[1] = new int[matrix.n];
matrix.Matrix[2] = new int[matrix.n];
matrix.Matrix[0][0] = 3;
matrix.Matrix[0][1] = 4;
matrix.Matrix[0][2] = -5;
matrix.Matrix[1][0] = 8;
matrix.Matrix[1][1] = 0;
matrix.Matrix[1][2] = 7;
matrix.Matrix[2][0] = 8;
matrix.Matrix[2][1] = 9;
matrix.Matrix[2][2] = -4;
WrappedVector vector = linearizedMatrix(matrix);
cout << vector << endl;
WrappedMatrix matrix1;
matrix1.n = 3;
matrix1.Matrix = new int * [matrix1.n];
matrix1.Matrix[0] = new int[matrix1.n];
matrix1.Matrix[1] = new int[matrix1.n];
matrix1.Matrix[2] = new int[matrix1.n];
matrix1.Matrix[0][0] = 8;
matrix1.Matrix[0][1] = 7;
matrix1.Matrix[0][2] = 7;
matrix1.Matrix[1][0] = -6;
matrix1.Matrix[1][1] = 0;
matrix1.Matrix[1][2] = 6;
matrix1.Matrix[2][0] = 2;
matrix1.Matrix[2][1] = 2;
matrix1.Matrix[2][2] = 9;
WrappedVector vector1 = linearizedMatrix(matrix1);
cout << vector1 << endl;
vector *= vector1;
cout << vector;
return 0;
}
提前谢谢你!
【问题讨论】:
-
您按值返回
WrappedMatrix。按值返回任何内容都需要该值具有正确的复制语义。您的WrappedMatrix没有正确的复制语义,因为它违反了Rule of 3。要么实现您在链接中看到的那些缺失的功能,要么使用std::vector<int>和std::vector<std::vector<int>>而不是int *和int **来省去麻烦。 -
同样,
WrappedVector也是如此。对你来说最简单的事情就是使用我提到的vector。这可以解决所有指针问题(但可能存在其他问题)。 -
注意:存储数组的数组可能会成为性能杀手。对于小型矩阵,通常会发现程序花费更多时间来追踪指针和加载缓存而不是处理数字。考虑使用单个 1 维数组或向量,并使用
row * number_columns + column自己执行 2D 1D 映射。 Example withstd::vector -
问自己一个简单的问题:既然您将
const引用传递给您的*=重载,那么您希望如何修改您传递的const对象?你不能(这里的例外情况不相关)。*=并没有按照您认为的方式工作。 -
@SamVarshavchik 实际上,更改
int ** Matrix指向的数据是可能的(只有外部指针不能在没有 const-casting 的情况下修改)。
标签: c++ matrix operator-overloading