回答
[id:lethevert:20070111:p1]
昔、C++を書いていたこともあったのだけれど、もうすっかり忘れていて、苦労した。なれない言語だと、くだらない間違いでもなかなか見つけられない。
テストコードは、こういう感じで。
Matrix matrix1(); Matrix matrix2(); int main (int argc, char** argv) { Matrix mat1 = matrix1(); Matrix mat2 = matrix2(); cout << endl << "matrix1 =" << endl << mat1; cout << endl << "matrix2 =" << endl << mat2; cout << endl << "matrix1 + matrix2 =" << endl << (mat1 + mat2); cout << endl << "matrix1 * matrix2 =" << endl << (mat1 * mat2); } Matrix matrix1() { Matrix mat(3); return mat.append(2, 1, 1) .append(3, 2, 2); } Matrix matrix2() { Matrix mat(3); return mat.append(2, 0, 1) .append(1, 1, 0) .append(3, 2, 2); }
以下、実装。ただ、この実装では、+ と * の計算量には問題があります。存在する要素だけに対して計算するようにすれば、もっと計算量は減る。
ああ、あとメモリリークとかはこの際無視で。(Javaは楽だなぁ。)
typedef int Item; class Matrix { private: struct Node { Item data; int row; int col; Node *nextrow; Node *nextcol; Node(Item i, int r, int c) { data = i; row = r; col = c; nextrow = 0; nextcol = 0;} }; int size; Node *rows; Node *cols; bool lt(int a1, int b1, int a2, int b2) { return a1 < a2 || (a1 == a2 && b1 < b2);} public: Matrix(int s) { size = s; rows = 0; cols = 0;} Matrix &append(Item i, int r, int c) { Node *n = new Node(i,r,c); { Node **m = &rows; while (*m && lt((*m)->row, (*m)->col, r, c)) m = &((*m)->nextrow); n->nextrow = *m; *m = n; } { Node **m = &cols; while (*m && lt((*m)->col, (*m)->row, c, r)) m = &((*m)->nextcol); n->nextcol = *m; *m = n; } return *this; } friend ostream &operator << (ostream &out, const Matrix &mat) { Node *n = mat.rows; for (int r=0; r<mat.size; ++r) { for (int c=0; c<mat.size; ++c) { out.width(5); out.setf(ios::right); if (n && n->row == r && n->col == c) { out << n->data; n = n->nextrow; } else { out << 0;} } out << endl; } return out; } friend Matrix operator + (const Matrix &m1, const Matrix &m2) { Node *n1 = m1.rows; Node *n2 = m2.rows; Matrix mat(m1.size); for (int r=0; r<mat.size; ++r) for (int c=0; c<mat.size; ++c) { Item i = 0; if (n1 && n1->row == r && n1->col == c) { i += n1->data; n1 = n1->nextrow; } if (n2 && n2->row == r && n2->col == c) { i += n2->data; n2 = n2->nextrow; } if (i) mat.append(i, r, c); } return mat; } friend Matrix operator * (const Matrix &m1, const Matrix &m2) { Matrix mat(m1.size); Node *n1 = m1.rows; for (int r=0; r<mat.size; ++r) { Node *_n1 = n1; Node *n2 = m2.cols; for (int c=0; c<mat.size; ++c) { n1 = _n1; Item i = 0; for (int k=0; k<mat.size; ++k) { if (n1 && n1->row == r && n1->col == k && n2 && n2->row == k && n2->col == c) { i += n1->data * n2->data;} if (n1 && n1->row == r && n1->col == k) { n1 = n1->nextrow;} if (n2 && n2->row == k && n2->col == c) { n2 = n2->nextcol;} } if (i) mat.append(i, r, c); } } return mat; } };