Advertisement
MagnusArias

PO1 | Matrix

Dec 9th, 2015
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.85 KB | None | 0 0
  1. // ------------------------------------------------------------------------------------------ MATRIX.H -------------------- //
  2.  
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. class WrongDimension{};     // wymiary macierzy
  8. class WrongDimension2{};    // wymiary macierzy
  9. class IndexOutOfRange{};    // przekroczenie zakresu tablicy
  10. class FileOpenError{};      // złe otwarcie pliku
  11.  
  12. class cMatrix
  13. {
  14.     private:
  15.         int col;
  16.         int row;
  17.  
  18.     public:
  19.         struct sMatrix;
  20.         sMatrix *matrix;
  21.  
  22.         // konstrktory i destruktor
  23.         cMatrix(int _row, int _col);
  24.         cMatrix(const cMatrix &wzor);
  25.         ~cMatrix();
  26.        
  27.  
  28.         int Col() const { return col; }
  29.         int Row() const { return row; }
  30.         void Wypelnij(char *nazwa);
  31.        
  32.         // operacje na macierzach
  33.         void operator+=(const cMatrix &B);
  34.         void operator-=(const cMatrix &B);
  35.         void operator*=(const cMatrix &B);
  36.  
  37.         //odczyt i zapis macierzy (operacja na pojedynczych elementach)
  38.         float& operator()(const int i, const int j);        // ZAPIS
  39.         float operator()(const int i, const int j) const;   // ODCZYT
  40.  
  41.         cMatrix& operator=(const cMatrix &B);  
  42.         friend ostream& operator<<(ostream& stream, const cMatrix &A);
  43. };
  44.  
  45. cMatrix operator+(const cMatrix &A, const cMatrix &B);
  46. cMatrix operator-(const cMatrix &A, const cMatrix &B);
  47. cMatrix operator*(const cMatrix &A, const cMatrix &B);
  48. bool operator==(cMatrix &A, cMatrix &B);
  49. ostream& operator<<(ostream& stream, const cMatrix &A);
  50.  
  51. void SetRow(char *nazwa);
  52.  
  53.  
  54.  
  55.  
  56.  
  57. // ------------------------------------------------------------------------------------------ MATRIX.CPP -------------------- //
  58.  
  59. #include <iostream>
  60. #include <fstream>
  61. #include "Matrix.h"
  62.  
  63. using namespace std;
  64.  
  65. struct cMatrix::sMatrix                     // ---------------------------------------------------------------------------------------------------- POCZĄTEK STRUKTURY
  66. {
  67.     float **data; // macierz
  68.     int n;  // licznik referencji
  69.     int r; // wiersze
  70.     int c; // kolumny
  71.  
  72.     sMatrix(int _r, int _c) // konstruktor
  73.     {
  74.         n = 1; // tworzymy obiekt więc liczba ref ustawiana na 1
  75.         r = _r;
  76.         c = _c;
  77.        
  78.         if(r<=0 || c<=0)
  79.             throw IndexOutOfRange();
  80.        
  81.         data = new float *[r];
  82.    
  83.         for (int i = 0; i < r; i++)
  84.             data[i] = new float[c];
  85.    
  86.         for (int i = 0; i < r; i++)
  87.             for (int j = 0; j < c; j++)
  88.                 data[i][j] = 0;
  89.     }
  90.  
  91.     sMatrix(int _r, int _c, float** t)
  92.     {
  93.         n = 1;
  94.         r = _r;
  95.         c = _c;
  96.        
  97.         if(r<=0 || c<=0)
  98.             throw IndexOutOfRange();
  99.        
  100.         data = new float *[r];
  101.  
  102.         for (int i = 0; i < r; i++)
  103.             data[i] = new float[c];
  104.  
  105.         for (int i = 0; i < r; i++)
  106.             for (int j = 0; j < c; j++)
  107.                 data[i][j] = t[i][j];
  108.     }
  109.  
  110.     ~sMatrix()
  111.     {
  112.         for (int i = 0; i < r; i++)
  113.             delete[] data[i];
  114.  
  115.         delete[] data;
  116.     };
  117.  
  118.     void wyp(float **tab)
  119.     {
  120.         for (int i = 0; i < r; i++)
  121.             for (int j = 0; j < c; j++)
  122.                 data[i][j] = tab[i][j];
  123.     }
  124.  
  125.     sMatrix* detach()
  126.     {
  127.         if (n == 1)
  128.             return this;
  129.  
  130.         sMatrix *t = new sMatrix(r, c, data); //jeżeli n > 1, to do danych odwołuje się jeszcze jakiś obiekt, więc tworzę kopie danych i na niej pracuję
  131.         n--;
  132.         return t;
  133.     }
  134.    
  135. };                  // ------------------------------------------------------------------------------------------------------------------------ KONIEC STRUKTURY
  136.  
  137.  
  138.                     // ------------------------------------------------------------------------------------------------------------------------ KONSTURKTORY I DESTRUKTOR
  139. cMatrix::cMatrix(int _row, int _col)
  140. {
  141.  
  142.     row = _row;
  143.     col = _col;
  144.  
  145.     matrix = new sMatrix(row, col);
  146. }
  147.  
  148. cMatrix::cMatrix(const cMatrix &wzor) // konstuktor kopiujący
  149. {
  150.     row = wzor.row;
  151.     col = wzor.col;
  152.     wzor.matrix->n++;
  153.     matrix = wzor.matrix;
  154. }
  155.  
  156.  
  157. cMatrix::~cMatrix()
  158. {
  159.     if (--(matrix->n) == 0) //zmniejszam ilosc odwołań do obiektu i jeżeli nic więcej się do niego nie odwołuje to usuwam
  160.         delete matrix;
  161.    
  162. }
  163.  
  164.  
  165.  
  166.  
  167.  
  168. //  -------------------------------------------------------------------------------------------------------------- FUNCKJE
  169.  
  170. void cMatrix::Wypelnij(char *nazwa)
  171. {
  172.     fstream file;
  173.     file.open(nazwa, ios::in);
  174.     float **temp;
  175.  
  176.     temp = new float *[row];
  177.  
  178.     for (int i = 0; i < row; i++)
  179.         temp[i] = new float[col];
  180.  
  181.     if (!file.good()) throw FileOpenError();
  182.    
  183.     file.seekg(3, ios_base::beg);
  184.  
  185.     for (int i = 0; i < row; i++)
  186.         for (int j = 0; j < col; j++)
  187.             file >> temp[i][j];
  188.    
  189.     matrix->wyp(temp);
  190.    
  191.     for (int i = 0; i < row; i++)
  192.         delete[] temp[i];
  193.  
  194.     delete[] temp;
  195.    
  196.     file.close();
  197. }
  198.  
  199.  
  200. cMatrix operator+(const cMatrix &A, const cMatrix &B)
  201. {
  202.     if(A.Row()!=B.Row() && A.Col()!=B.Col()) throw WrongDimension();
  203.    
  204.     cMatrix C(A.Row(),A.Col());
  205.  
  206.     for (int i = 0; i < A.Row(); i++)
  207.     {
  208.         for (int j = 0; j < A.Col(); j++)
  209.         {      
  210.             if(i>=A.Row() || j>=B.Col()) throw IndexOutOfRange();
  211.            
  212.             C(i, j) = A(i, j) + B(i, j);
  213.         }
  214.     }
  215.  
  216.     return C;
  217. }
  218.  
  219. void cMatrix::operator+=(const cMatrix &B)
  220. {
  221.     if(row!=B.Row() && col!=B.Col()) throw WrongDimension();
  222.    
  223.     for (int i = 0; i < row; i++)
  224.     {
  225.         for (int j = 0; j < col; j++)
  226.         {
  227.             if(i>=row || j>=col) throw IndexOutOfRange();
  228.            
  229.             matrix->data[i][j] += B(i,j);
  230.         }
  231.     }
  232. }
  233.  
  234.  
  235. cMatrix operator-(const cMatrix &A, const cMatrix &B)
  236. {
  237.     if(A.Row()!=B.Row() && A.Col()!=B.Col()) throw WrongDimension();
  238.    
  239.     cMatrix C(A.Row(), A.Col());
  240.  
  241.     for (int i = 0; i < A.Row(); i++)
  242.     {
  243.         for (int j = 0; j < A.Col(); j++)
  244.         {
  245.             if(i>=A.Row() || j>=A.Col()) throw IndexOutOfRange();
  246.            
  247.             C(i, j) = A(i, j) - B(i, j);
  248.         }
  249.     }
  250.  
  251.     return C;
  252. }
  253.  
  254. void cMatrix::operator-=(const cMatrix &B)
  255. {
  256.     if(row!=B.Row() && col!=B.Col()) throw WrongDimension();
  257.  
  258.     for (int i = 0; i < row; i++)
  259.     {
  260.         for (int j = 0; j < col; j++)
  261.         {
  262.             if(i>=row || j>=col)
  263.                 throw IndexOutOfRange();
  264.            
  265.             matrix->data[i][j] -= B(i,j);
  266.         }
  267.     }
  268. }
  269.  
  270.  
  271. cMatrix operator*(const cMatrix &A, const cMatrix &B)
  272. {
  273.     if( A.Col() != B.Row() ) throw WrongDimension();
  274.    
  275.     cMatrix C(A.Row(),B.Col());
  276.  
  277.     for (int i = 0; i < A.Row(); i++)
  278.     {
  279.         for (int j = 0; j < B.Col(); j++)
  280.         {
  281.             for (int k = 0; k < A.Col(); k++)
  282.             {
  283.                 if(i>=A.Row() || j>=B.Col() || k>=A.Col())
  284.                     throw IndexOutOfRange();
  285.                
  286.                 C(i, j) += A(i, k) * B(k, j);
  287.             }
  288.         }
  289.     }
  290.  
  291.     return C;
  292. }
  293.  
  294. void cMatrix::operator*=(const cMatrix &B)
  295. {
  296.     if( col != B.Row() ) throw WrongDimension();
  297.    
  298.     cMatrix C(row, B.Col());
  299.  
  300.     for (int i = 0; i < matrix->r; i++)
  301.     {
  302.         for (int j = 0; j < B.matrix->c; j++)
  303.         {
  304.             for (int k = 0; k < matrix->c; k++)
  305.             {
  306.                 if(i>=matrix->r || j>=B.matrix->c || k>=matrix->c)
  307.                 {
  308.                     throw IndexOutOfRange();
  309.                 }
  310.                
  311.                 C(i, j) += matrix->data[i][k] * B(k, j);
  312.             }
  313.         }
  314.     }
  315.     for (int i = 0; i < matrix->r; i++)
  316.     {
  317.         for (int j = 0; j < B.matrix->c; j++)
  318.         {
  319.                 if(i>=matrix->r || j>=B.matrix->c)
  320.                     throw IndexOutOfRange();
  321.                
  322.                 matrix->data[i][j] = C(i, j);
  323.         }
  324.     }
  325.     col = B.Col();
  326. }
  327.  
  328.  
  329. float& cMatrix::operator()(const int i, const int j)                                        // ZAPIS
  330. {
  331.     matrix = matrix->detach();
  332.     return matrix->data[i][j];
  333. }
  334.  
  335. float cMatrix::operator()(const int i, const int j) const { return matrix->data[i][j]; }    // ODCZYT
  336.  
  337.  
  338. cMatrix& cMatrix:: operator=(const cMatrix &B)
  339. {
  340.     if (matrix->n == 1)
  341.     {
  342.         delete matrix;
  343.         matrix = B.matrix;
  344.         matrix->n++; //zwiekszam bo kolejny obiekt odwołuje się do danych
  345.     }
  346.     else
  347.     {
  348.         matrix->n--; // nie kopiuje zawartości danych, tylko przekazuje adres
  349.         matrix = B.matrix;
  350.     }
  351.     return *this;
  352.  
  353. }
  354.  
  355.  
  356. ostream& operator<<(ostream& stream, const cMatrix &A)
  357. {
  358.     cout << "Macierz: " << A.row << " x " << A.col << endl;
  359.    
  360.     for (int i = 0; i < A.row; i++)
  361.     {
  362.         cout << endl;
  363.         for (int j = 0; j < A.col; j++)
  364.             cout << " " << A(i,j);
  365.     }
  366.     cout << endl << endl << endl;
  367.     return stream;
  368. }
  369.  
  370.  
  371. bool operator==(cMatrix &A, cMatrix &B)
  372. {
  373.     for (int i = 0; i < A.Row(); i++)
  374.         for (int j = 0; j < A.Col(); j++)
  375.             if (A(i, j) != B(i, j))
  376.                 return false;
  377.  
  378.     return true;
  379. }
  380.  
  381.  
  382.  
  383.  
  384.  
  385. // ------------------------------------------------------------------------------------------ MAIN.CPP -------------------- //
  386.  
  387. #include <iostream>
  388. #include "Matrix.h"
  389. #include <fstream>
  390.  
  391. using namespace std;
  392.  
  393. static int row1;
  394. static int col1;
  395.  
  396. int main()
  397. {                                                                                                                       // MAIN
  398.     try
  399.     {
  400.         SetRow((char*)"A.txt");
  401.         cMatrix A(row1, col1);
  402.         A.Wypelnij((char*)"A.txt");
  403.         cout << A;
  404.  
  405.         SetRow((char*)"B.txt");
  406.         cMatrix B(row1, col1);
  407.         B.Wypelnij((char*)"B.txt");
  408.         cout << B;
  409.  
  410.         cMatrix C(A.Row(), B.Col()); // macierz wynikowa
  411.  
  412.         int wybor;
  413.         do{
  414.             cout << "1 - Dodawanie" << endl;
  415.             cout << "2 - Odejmowanie" << endl;
  416.             cout << "3 - Mnozenie" << endl;
  417.             cout << "4 - Porownywanie" << endl;
  418.             cout << "5 - Wyjscie" << endl;
  419.  
  420.             cin >> wybor;
  421.             cout << endl;
  422.  
  423.             switch (wybor)
  424.             {
  425.             case 1:
  426.             {
  427.                       cout << "Operator + " << endl;
  428.                       C = A + B;
  429.                       cout << endl;
  430.                       cout << "A + B = " << endl;
  431.                       cout << C;
  432.                       cout << endl << endl;
  433.  
  434.                       cout << "Operator += " << endl;
  435.                       A += B;
  436.                       cout << endl;
  437.                       cout << "A + B = " << endl;
  438.                       cout << A;
  439.                       cout << endl << endl;
  440.                       break;
  441.             }
  442.  
  443.             case 2:
  444.             {
  445.                       cout << "Operator - " << endl;
  446.                       C = A - B;
  447.                       cout << endl;
  448.                       cout << "A - B = " << endl;
  449.                       cout << C;
  450.                       cout << endl << endl;
  451.  
  452.                       cout << "Operator -= " << endl;
  453.                       A -= B;
  454.                       cout << endl;
  455.                       cout << "A - B = " << endl;
  456.                       cout << A;
  457.                       cout << endl << endl;
  458.                       break;
  459.             }
  460.  
  461.             case 3:
  462.             {
  463.                       cout << "Operator * " << endl;
  464.                       C = A * B;
  465.                       cout << endl;
  466.                       cout << "A * B = " << endl;
  467.                       cout << C;
  468.                       cout << endl << endl;
  469.  
  470.                       cout << "Operator *= " << endl;
  471.                       A *= B;
  472.                       cout << endl;
  473.                       cout << "A * B = " << endl;
  474.                       cout << A;
  475.                       cout << endl << endl;
  476.                       break;
  477.             }
  478.  
  479.             case 4:
  480.             {
  481.                       cout << endl;
  482.                       if (A == B)
  483.                       {
  484.                           cout << "Macierze sa sobie rowne" << endl;
  485.                       }
  486.                       else
  487.                       {
  488.                           cout << "Macierze nie sa sobie rowne" << endl;
  489.                       }
  490.                       cout << endl << endl;
  491.                       break;
  492.             }
  493.  
  494.             default: if (wybor != 5) cout << "WYBRALES ZLA OPCJE!!" << endl;
  495.             }
  496.         } while (wybor != 5);
  497.  
  498.         cout << endl << endl;
  499.     }                                                                               // TRY
  500.    
  501.  
  502.     // obsługa błędów
  503.     catch(WrongDimension&)  {   cout << endl << "ERROR: ZLE WYMIARY MACIERZY! WIELKOSCI MACIERZY MUSZA BYC JEDNAKOWE!!"                                 << endl << endl; }
  504.     catch(WrongDimension2&) {   cout << endl << "ERROR: ZLE WYMIARY MACIERZY! LICZBA KOLUMN MACIERZY A MUSI BYC ROWNA LICZBIE WIERSZY MACIERZY B!!"     << endl << endl; }
  505.     catch(IndexOutOfRange&) {   cout << endl << "ERROR: INDEKS TABLICY POZA PRZEDZIALEM!"                                                               << endl << endl; }
  506.     catch(FileOpenError&)   {   cout << endl << "ERROR: BLAD OTWARCIA PLIKU!"                                                                           << endl << endl; }
  507.  
  508.     return 0;
  509. }                                                                                                                       // MAIN
  510.  
  511. void SetRow(char *nazwa)
  512. {
  513.     fstream file;
  514.     file.open(nazwa, ios::in);
  515.    
  516.     if (!file.good()) throw FileOpenError();
  517.    
  518.     file >> row1;
  519.     file >> col1;
  520.  
  521.     file.close();
  522.    
  523. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement