#8 Stepan
Kedysi som mal ako semestralku tiez podobnu ulohu (az na to ze trebalo spravyt aj nasobenie a delenie matic, inverzne matice a determinanty ). Teraz som si to skusil napisat pomocou stl a c++11 a naprogramoval som to niekolkokrat rychlejsie a kod je ovela jednoduhsi:
#include <vector>
#include <algorithm>
#include <iostream>
#include <initializer_list>
#include <random>
template <typename Data>
class Matrix{
using size_t = std::size_t ;
typedef std::vector<Data> line_t;
typedef const line_t cline_t;
std::vector<line_t> data;
public:
struct Size{
size_t riadky;
size_t stlpce;
bool operator==(Size s){return riadky == s.riadky && stlpce == s.stlpce;}
bool operator!=(Size s){return riadky != s.riadky || stlpce != s.stlpce;}
operator size_t()const{return riadky*stlpce;}
Size(size_t riadky, size_t stlpce):riadky(riadky), stlpce(stlpce){}
};
Size size()const{return Size{data.size(), (data.empty()?0:data[0].size())};}
template <typename Fnc>
void for_each(Fnc f = Fnc()){
Size s = size();
for(size_t r = 0; r < s.riadky; ++r)
for(size_t c = 0; c < s.stlpce; ++c)
f(data[r][c]);
}
template <typename Fnc>
void for_each2(const Matrix& m, Fnc f = Fnc()){
Size s = size();
if(s != m.size())throw Size(0,0);
for(size_t r = 0; r < s.riadky; ++r)
for(size_t c = 0; c < s.stlpce; ++c)
f(data[r][c], m[r][c]);
}
line_t& operator[](size_t s){return data[s];}
cline_t& operator[](size_t s)const{return data[s];}
Matrix(Size size, Data def_value = 0):data(size.riadky, line_t(size.stlpce, def_value)){}
Matrix(size_t r, size_t c, Data def_value = 0):data(r, line_t(c, def_value)){}
Matrix(const Matrix& m):data(m.data){}
Matrix(Matrix&& m):data(std::move(m.data)){}
Matrix(std::initializer_list<line_t>&& inic):data(std::move(inic)){}
Matrix& operator=(const Matrix& m){data = m.data;return *this;}
Matrix& operator=(Matrix&& m){data = std::move(m.data);return *this;}
Matrix& operator=(std::initializer_list<line_t>&& inic){data = std::move(inic);return *this;}
Matrix& operator=(const Data& d){for_each([&d](Data& x){x = d;});return *this;}
Matrix& operator+=(const Matrix& m){for_each2(m, [](Data& a, const Data& b){a += b;});return *this;}
Matrix& operator-=(const Matrix& m){for_each2(m, [](Data& a, const Data& b){a -= b;});return *this;}
Matrix operator+(const Matrix& m)const{Matrix tmp(*this);tmp += m;return tmp;}
Matrix operator-(const Matrix& m)const{Matrix tmp(*this);tmp -= m;return tmp;}
};
//edit:
template <typename D>
std::ostream& operator<<(std::ostream& out, const Matrix<D>& m){
auto s = m.size();
out << "\n[";
for(size_t r = 0; r < s.riadky; ++r){
for(size_t c = 0; c < s.stlpce; ++c){
out << m[r][c];
if(c != (s.stlpce-1))out << ", ";
}
if(r != (s.riadky-1))out << '\n';
}
out << "]\n";
return out;
}
int main(){
using namespace std;
Matrix<int> m1(2, 2); //2x2
Matrix<int> m2{{4,3}, {2,1}}; //trochu nebezpecna inicializacia, ale to nevadi :)
m1.for_each([](int& i){i=std::rand()%20;});
cout << m1 << "+" << m2 << "=" << (m1+m2) << endl;
//Matice plne matic:
Matrix<Matrix<double>> wtf_m1(4, 2, Matrix<double>(4, 2, 3.14));
Matrix<Matrix<double>> wtf_m2(4, 2, Matrix<double>(4, 2, -2.14));
auto wtf_m3 = wtf_m1 + wtf_m2; // xD
cout << "\n\nwtf_m3[1][0]="<< wtf_m3[1][0];
}