问题描述
所以我得到了我的数据结构和算法项目。我基本上需要开发一个具有以下属性的类 Matrix:
- list
- >>,(其中只有矩阵的非零元素。某个元素的值存储为pair的第二个参数,a的第一个参数pair 表示该元素位于原始矩阵中的实际列)
- vector rows,(rows[i] - 分别代表上述列表列表中每个列表的实际行)
- 实际行数,
- 实际列数。
到目前为止,在我的项目中,我已经开发了特定的构造函数、矩阵相加和相减等。我唯一不能做的是将类 Matrix 的两个实例相乘,这意味着我无法为类矩阵。
问题说明:
实例 A:
list<list<pair<int,double>>>: {{{10,5},{40,15}},{{50,25}},{{80,35}}}
vector<int>: {2,10,70};
actual number of rows: 100
actual number of columns: 100
实例 B:
list<list<pair<int,double>>>: {{{1,6},{2,{3,7}},{{3,4}},1}}}
vector<int>: {1,2,33};
actual number of rows: 100
actual number of columns: 100
显然,乘法是为这些矩阵定义的,因为矩阵 A 的列数等于矩阵 B 的行数。 我无法找到正确的算法来乘以这些矩阵。 有人可以用短线写出什么是乘以这些的算法之一。
解决方法
主要思想在于使用方便的原语来设置/获取矩阵位置 (i,j) 处的值、行数和列数。
为了简单起见,我在以下代码中将您的顶级列表替换为一个向量(因为您可以随机访问第 i 个值,所以效率更高):
#include <cassert>
#include <iostream>
#include <list>
#include <vector>
using namespace std;
class Matrix {
private:
vector<list<pair<unsigned,double>>> data;
unsigned m;
unsigned n;
public:
Matrix(unsigned m,unsigned n):
m(m),n(n),data(m)
{}
inline unsigned num_rows() const {
return m;
}
inline unsigned num_columns() const {
return n;
}
double get(unsigned i,unsigned j) const {
for (pair<unsigned,double> p : data[i]) {
if (p.first == j) return p.second;
}
return 0.0;
}
void set(unsigned i,unsigned j,double v) {
for (pair<unsigned,double> p : data[i]) {
if (p.first == j) {
p.second = v;
return;
}
}
if (v) {
data[i].push_back(make_pair(j,v));
}
}
};
Matrix operator * (const Matrix & a,const Matrix & b) {
unsigned m = a.num_rows(),n = b.num_columns(),k_max = a.num_columns();
assert (a.num_columns() == b.num_rows());
Matrix c(m,n);
for (unsigned i = 0; i < m; i++) {
for (unsigned j = 0; j < n; j++) {
double value = 0;
for (unsigned k = 0; k < k_max; k++) {
value += a.get(i,k) * b.get(k,j);
}
if (value) c.set(i,j,value);
}
}
return c;
}
ostream & operator << (ostream & out,const Matrix & a) {
for (unsigned i = 0; i < a.num_rows(); i++) {
for (unsigned j = 0; j < a.num_columns(); j++) {
out << a.get(i,j) << "\t";
}
out << endl;
}
return out;
}
int main() {
Matrix a(2,3),b(3,1);
for (unsigned i = 0; i < a.num_rows(); i++) {
for (unsigned j = 0; j < a.num_columns(); j++) {
a.set(i,10 * i + j);
}
}
for (unsigned i = 0; i < b.num_rows(); i++) {
for (unsigned j = 0; j < b.num_columns(); j++) {
b.set(i,10 * (i + 1));
}
}
Matrix c = a * b;
cout << "a:" << endl << a << endl
<< "b:" << endl << b << endl
<< "c:" << endl << c << endl
;
return 0;
}
结果:
a:
0 1 2
10 11 12
b:
10
20
30
c:
80
680