// #include "stdafx.h"
#include <iostream>
#include <iomanip>
//#include <cstdlib>
#include <ctime>
//#include <exception>
#include <stdexcept>
//#include <matrix.h>
using namespace std;
class Array
{
protected:
int** _data;
int _cols, _rows;
public:
Array(void) : _data(0), _rows(0),_cols(0) {};
Array(int rows, int cols, bool fill=false, int filler=0)
: _rows(rows), _cols(cols), _data(0)
{
_data = new int* [_rows];
for (int i=0; i<_rows; i++)
{
_data[i] = new int[_cols];
if (fill)
for (int j=0; j<_cols; j++)
_data[i][j] = filler;
}
}
Array(const Array& other) :
_cols(other.cols()),
_rows(other.rows())
{
_data = new int* [_rows];
for (int i=0; i<_rows; i++)
{
_data[i] = new int[_cols];
for (int j=0; j<_cols; j++)
_data[i][j] = other._data[i][j];
}
}
// транспонируем матрицу
const Array transpon() const
{
Array C(_cols, _rows);
for (int i=0; i<_cols; i++)
for (int j=0; j<_rows; j++)
C[i][j] = _data[j][i];
return C;
}
// сложение двух матриц
const Array operator+(const Array& other) const
{
if ((_cols != other.cols()) || (_rows != other.rows()))
throw out_of_range("матрицы не имеют");
Array C(_rows, _cols);
for (int i=0; i<C.rows(); i++)
for (int j=0; j<C.cols(); j++)
C._data[i][j] = _data[i][j] + other._data[i][j];
return C;
}
//вычитание двух матриц
const Array operator-(const Array& other) const
{
if ((_cols != other.cols()) || (_rows != other.rows()))
throw out_of_range("Multiplied matrixes do not have same number of cols and rows.");
Array C(_rows, _cols);
for (int i=0; i<C.rows(); i++)
for (int j=0; j<C.cols(); j++)
C._data[i][j] = _data[i][j] - other._data[i][j];
return C;
}
// умножение двух матриц
const Array operator*(const Array& other) const
{
if (_cols != other.rows())
throw out_of_range("Multiplied matrixes do not have same number of cols and rows.");
Array C(_rows, other.cols(), true);
for (int i=0; i<C.rows(); i++)
for (int j=0; j<C.cols(); j++)
for (int k=0; k<_cols; k++)
C[i][j] += _data[i][k]*other._data[k][j];
return C;
}
//сдвиг на 1 влево
const Array operator<<(const Array& other) const
{
// void left( int a[], int N){
// int temp=a[0];
// for (int i=0; i<N-1;i++) a[i]=a[i+1];
// a[N-1]=temp;
}
// присваивание матрицы
Array& operator= (const Array& other)
{
if (this!=&other)
{
if (_data!=0)
{
for (int i=0; i<_rows; i++)
delete [] _data[i];
delete [] _data;
}
_rows = other.rows();
_cols = other.cols();
_data = new int* [_rows];
for (int i=0; i<_rows; i++)
_data[i] = new int[_cols];
for (int i=0; i<_rows; i++)
for (int j=0; j<_cols; j++)
_data[i][j] = other._data[i][j];
}
return *this;
}
friend ostream& operator<< (ostream& o, const Array& a)
{
for (int i=0; i<a._rows; i++)
{
for (int j=0; j<a._cols; j++)
o << setw(4) << a._data[i][j];
o << endl;
}
return o;
}
void fill_random()
{
for (int i=0; i<_rows; i++)
for (int j=0; j<_cols; j++)
_data[i][j] = rand()%100+1;
}
int* operator[](int i) { return _data[i]; }
int& at(int i, int j) { return _data[i][j]; }
const int cols() const { return _cols; }
const int rows() const { return _rows; }
~Array()
{
if (_data!=0)
{
for (int i=0; i<_rows; i++)
delete [] _data[i];
delete [] _data;
}
}
};
int main()
{
srand(static_cast<unsigned int>(time(0)));
int N,M,K;
cin>>N>>M>>K;
Array x(N, M, true, 1);
Array y(N, M, true, 1);
Array z(N, K);
z.fill_random();
cout << (x*y) << endl;
cout << (x+y) << endl;
cout << z << endl << z.transpon() << endl;
return 0;
}