Zadanie
zadana tablica, przesuwajace sie okno i znalezc liczbe niepowtarzalnych elementow
#include<stdio.h>
void checkit(int t[],int s,int w)
{
if(w>s)
{
printf("okno wieksze niz rozmiar tablicy");
return;
}
int maxwindowindex=s-w;
int licz=0;
int difflicz=0;
int localdiff=0;
for(int i=0;i<=maxwindowindex;i++) //loop for moving "window"
{
difflicz=0;
for(int k=0;k<w;k++) //loop changing the checked item
{
licz=w;
for(int j=0;j<w;j++) //loop comparing the checked element with other elements of the window
{
licz--;
if(t[i+k] != t[i+licz] )
{
localdiff++;
}
}
if(localdiff==(w-1))
{
difflicz++;
}
localdiff=0;
}
printf("w okienku nr %d mamy %d niepowtarzalne elementy \n",i+1,difflicz);
printf("\n");
}
return;
}
int main()
{
int tab[]={1,2,3,4,5,5,7,8,9,10};
int size=sizeof(tab)/(sizeof(int));
int window=3;
printf("\nwielkosc twojej tablicy to %d, rozmiar okna to %d \n",size, window);
printf("w takiej konfiguracji masz %d roznych polozen okna\n\n",size-window+1);
checkit(tab,size,window);
return 0;
}
Zadanie1
Inteligentny wskaźnik
Napisz swoją implementację wskaźnika:
bez licznika referencji
szablon
semantyka przenoszenia
operatory * -> == != < <= > >=
void swap(?, ?)
funkcja get()
z licznikiem referencji
szablon
kopiowanie + przenposzenie
blok kontrolny
brak weak_ptr
operatory * -> == != < <= > >=
void swap(?, ?)
funkcja get()
Zadanie 2:
Ring Buffer
Napisać implementację RingBuffer:
RingBuffer - potrafi przechowywać maksymalnie N elementów
https://en.wikipedia.org/wiki/Circular_buffer
RingBuffer ma być kontenerem STL
ma wspierać range for oraz podstawowe algorytmy STL'a
Zadanie3:
Matrix<M,N,T>
Napisać implementację:
posiada operatory:
dodawania macierzy (+)
mnożenia macierzy (+)
dodawania skalara do macierzy (+)
mnożenia macierzy przez skalar (+)
dostarcza konstruktory:
domyślny
kopiujący (+)
przesuwający*
Zadanie dodatkowe: gdzie występuje (+) implementacja ma działać dla typu T1 który jest konwertowalny do typu T
Rozwiązania GIT
https://github.com/JanosikOpryszek/kod/tree/master/ZUT/zadania
zadanie 1
#include <iostream>
#include <vector>
using namespace std;
// smart wskaznik bez licznika referencji - wskaznik wylaczny jak unique_ptr
template <typename T>
class Unique
{
public:
Unique(){ // konstruktor bezparametrowy
pointer = nullptr;
}
Unique(T* ptr){ // konstruktor z parametrem
pointer = ptr;
}
~Unique(){ //destruktor
delete pointer;
}
T* get(){ //funkcja get
return pointer;
}
void swap(Unique& other){ //funkcja swap
T* tmp = pointer;
pointer = other.pointer;
other.pointer = tmp;
}
Unique(Unique&& other){ //konstruktor przenoszacy
T* tmp = pointer;
pointer = other.pointer;
other.pointer = nullptr;
}
T operator * (){ // operator *
if(pointer)
return *(pointer);
else
return 0;
}
bool operator==(const Unique& other){ // operator ==
if(pointer && other.pointer )
{
if(*pointer == *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator != (const Unique& other){ // operator !=
if(pointer && other.pointer )
{
if(*pointer != *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator < (const Unique& other){ // operator <
if(pointer && other.pointer )
{
if(*pointer < *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator <= (const Unique& other){ // operator <=
if(pointer && other.pointer )
{
if(*pointer <= *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator > (const Unique& other){ // operator >
if(pointer && other.pointer )
{
if(*pointer > *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator >= (const Unique& other){ // operator >=
if(pointer && other.pointer )
{
if(*pointer >= *other.pointer)
return true;
else
return false;
}
else
return 0;
}
private: //prywatny, blokowanie uzycia konst. kopiujacego i operatora przypisania
Unique(const Unique& other) {}; // kopiujacy
Unique& operator=(const Unique& other){} // operator przypisania
T* pointer;
};
//**********************************************************************************
// smart wskaznik z licznikiem referencji - wskaznik wspoldzielony jak shared_ptr
template <typename T>
class Shared
{
public:
Shared(T* ptr): pointer(ptr),licznik(new int){ // konstruktor z parametrem
*licznik=1;
}
Shared(const Shared<T>& other) { // konstruktor kopiujacy
licznik=other.licznik;
pointer=other.pointer;
(*licznik)++;
}
Shared(Shared&& other){ //konstruktor przenoszacy
pointer = other.pointer;
licznik=other.licznik;
delete other; // albo pointer i licznik
}
~Shared(){ //destruktor
if(*licznik>1)
{
(*licznik)--;
}
else if (*licznik==1)
{
delete pointer;
delete licznik;
}
}
T* get(){ //funkcja get
return pointer;
}
void swap(Shared& other){ //funkcja swap
T* tmp = pointer;
pointer = other.pointer;
other.pointer = tmp;
int* tmp2 = licznik;
licznik = other.licznik;
other.licznik = tmp2;
}
int ile(){ //funkcja ile
return *licznik;
}
void operator=(const Shared<T>& other){ // operator przypisania z innego wskaznika
cout << "operator przypisania\n";
if(pointer)
{
*pointer = *other.pointer;
licznik=other.licznik;
*licznik++;
}
else
{
pointer=new T;
*pointer=*other.pointer;
licznik=other.licznik;
*licznik++;
}
}
void reset(int wartosc){ // funkcja przypisania wartosci
*pointer = wartosc;
}
T operator * (){ // operator *
if(pointer)
return *(pointer);
else
return 0;
}
bool operator==(const Shared& other){ // operator ==
if(pointer && other.pointer )
{
if(*pointer == *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator != (const Shared& other){ // operator !=
if(pointer && other.pointer )
{
if(*pointer != *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator < (const Shared& other){ // operator <
if(pointer && other.pointer )
{
if(*pointer < *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator <= (const Shared& other){ // operator <=
if(pointer && other.pointer )
{
if(*pointer <= *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator > (const Shared& other){ // operator >
if(pointer && other.pointer )
{
if(*pointer > *other.pointer)
return true;
else
return false;
}
else
return 0;
}
bool operator >= (const Shared& other){ // operator >=
if(pointer && other.pointer )
{
if(*pointer >= *other.pointer)
return true;
else
return false;
}
else
return 0;
}
private:
T* pointer;
int* licznik;
};
void foo(Unique<int> argu){
cout << "------------------z wnetrza funkcji to co dal przeslany argument: "<<*argu << endl;
}
Unique<int> foo2(Unique<int> argu){
cout << "------------------z wnetrza funkcji to co dal przeslany argument: "<<*argu << endl;
return move(argu);
}
void foos(Shared<int> argu){
cout << "------------------z wnetrza funkcji, kopia argumentu ma wartosc: "<<*argu << endl;
cout << "------------------z wnetrza funkcji ile= "<< argu.ile()<< endl;;
}
int main()
{
cout << "****************************************************************************************\n";
cout << "Klasa Unique - smart wskaznik bez licznika referencji - wskaznik wylaczny jak unique_ptr \n";
cout << "tworze wskaznik 'c' z wartoscia 10\n";
Unique<int> c(new int(10));
cout << "tworze wskaznik 'inny' z wartoscia 100\n";
Unique<int> inny(new int(100));
cout << "\n";
cout <<"c.get() wyswietla adres: ";
cout << c.get() << "\n";
cout <<"*(c.get()) wyswietla wartosc: ";
cout << *(c.get()) << "\n";
cout <<"przeciazony *c wyswietla wartosc: ";
cout << *c << "\n";
cout << "\n";
cout << "zamieniam 'inny' z 'c' za pomoca inny.swap(c) \n";
inny.swap(c);
cout << "inny.get() wyswietla : ";
cout << inny.get() << "\n";
cout <<"*inny wyswietla: ";
cout << *inny << "\n";
cout <<"c.get() wyswietla: ";
cout << c.get() << "\n";
cout <<"*c wyswietla: ";
cout << *c << "\n";
cout << "\n";
cout << "tworze nowy 'cc' konstruktorem przenoszacym z 'inny' cc(move(inny)), 'inny' powinien sie wyzerowac, 'cc' byc jak 'inny'\n";
Unique<int> cc(move(inny));
cout << "inny.get() wyswietla : ";
cout << inny.get() << "\n";
cout << "*inny wyswietla : ";
cout << *inny << "\n";
cout <<"cc.get() wyswietla: ";
cout << cc.get() << "\n";
cout <<"*cc wyswietla: ";
cout << *cc << "\n";
cout << "\n";
//foo(c); nie zadziala bo kopiujacy w obszarze prywatnym
cout << "funkcja foo, pointer 'c' jako argument funkcji - przeslany konstruktorem przenoszacym foo(move(c))\n";
foo(move(c));
cout << "*c po przeniesieniu do argumentu funkcji wyswietla : ";
cout << *c << "\n\n";
cout << "funkcja foo2 ktora przyjmuje argument 'cc' i zwraca do 'odb' za pomoca konstruktora przenoszacego \n";
Unique<int> odb( foo2(move(cc)) );
cout <<"*cc wyswietla: ";
cout << *cc << "\n";
cout <<"*odb wyswietla: ";
cout << *odb << "\n";
cout << "\n";
cout << "operator == \n";
cout << "tworze wskaznika 'a' z wartoscia 5\n";
Unique<int> a(new int(5));
cout << "tworze wskaznika 'b' z wartoscia 5\n";
Unique<int> b(new int(5));
cout << "a == b : ";
if (a == b)
cout << "rowne\n";
else
cout << "rozne\n";
cout << "\n";
cout << "operator != \n";
cout << "a != b : ";
if (a != b)
cout << "rozne\n";
else
cout << "nie rozne\n";
cout << "\n";
cout << "operator < \n";
cout << "a < cc : ";
if (a != cc)
cout << "prawda\n";
else
cout << "falsz\n";
cout << "\n";
cout << "*********************************************************************************************\n";
cout << "Klasa Shared - smart wskaznik z licznikiem referencji - wskaznik wspoldzielony jak shared_ptr \n";
cout << "tworze wskaznik 's' z wartoscia 7\n";
Shared<int> s(new int(7));
cout << "ile obiektow typu s : " << s.ile() << endl;
cout << "\n";
cout << "tworze wskaznik 's2' z wartoscia 10\n";
Shared<int> s2(new int(10));
cout << "ile obiektow typu s : " << s2.ile() << endl;
cout << "przypisanie do powyzszego wskaznika 's2' wartosci 11 za pomoca s2.reset(11) \n";
s2.reset(11);
cout << "*s2=" << *s2 <<"\n";
cout << "ile obiektow typu s2: " << s2.ile() << endl;
cout << "\n";
cout << "wywolanie funkcji foos(s2) czyli stworzenie kopi przez przeslanie argumentu\n";
foos(s2);
cout << "po wyjsciu z funkcji: ";
cout << "ile obiektow typu s2 : " << s2.ile() << endl;
cout << "\n";
cout << "vector typu Shared<int> i dodane typu <int>\n";
// umiesc wskazniki w kontenerze
vector<Shared<int>> whoMadeCoffee;
cout <<"zaczynam pushback\n";
whoMadeCoffee.push_back(s);
cout << "byl push s\n";
whoMadeCoffee.push_back(s);
cout << "byl push s\n";
whoMadeCoffee.push_back(s2);
cout << "byl push s2\n";
whoMadeCoffee.push_back(s);
cout << "byl push s\n";
whoMadeCoffee.push_back(s2);
cout << "byl push s2\n\n";
cout << "wyswietlam rangefor:\n";
// wypisz wszystkie elementy
for (auto &ptr : whoMadeCoffee) {
cout << *ptr << " ";
}
cout << "\nrangefor koniec\n";
cout << endl ;
cout << "ile obiektow s : " << s.ile() << endl;
cout << "ile obiektow vector[s] : " << whoMadeCoffee[1].ile() << endl;
cout << "\n";
cout << "ile obiektow vector[s2] : " << whoMadeCoffee[2].ile() << endl;
cout << "\n";
cout << "tworze wskaznik 'ch' typu <char> z wartoscia 8\n";
Shared<char> ch(new char(7));
cout << "ile obiektow typu ch: " << ch.ile() << endl;
cout << "ile obiektow typu s2 : " << s2.ile() << endl;
return 0;
}
.
wynik:
****************************************************************************************
Klasa Unique - smart wskaznik bez licznika referencji - wskaznik wylaczny jak unique_ptr
tworze wskaznik 'c' z wartoscia 10
tworze wskaznik 'inny' z wartoscia 100
c.get() wyswietla adres: 0x7d1120
*(c.get()) wyswietla wartosc: 10
przeciazony *c wyswietla wartosc: 10
zamieniam 'inny' z 'c' za pomoca inny.swap(c)
inny.get() wyswietla : 0x7d1120
*inny wyswietla: 10
c.get() wyswietla: 0x7d1190
*c wyswietla: 100
tworze nowy 'cc' konstruktorem przenoszacym z 'inny' cc(move(inny)), 'inny' powinien sie wyzerowac, 'cc' byc jak 'inny'
inny.get() wyswietla : 0
*inny wyswietla : 0
cc.get() wyswietla: 0x7d1120
*cc wyswietla: 10
funkcja foo, pointer 'c' jako argument funkcji - przeslany konstruktorem przenoszacym foo(move(c))
------------------z wnetrza funkcji to co dal przeslany argument: 100
*c po przeniesieniu do argumentu funkcji wyswietla : 0
funkcja foo2 ktora przyjmuje argument 'cc' i zwraca do 'odb' za pomoca konstruktora przenoszacego
------------------z wnetrza funkcji to co dal przeslany argument: 10
*cc wyswietla: 0
*odb wyswietla: 10
operator ==
tworze wskaznika 'a' z wartoscia 5
tworze wskaznika 'b' z wartoscia 5
a == b : rowne
operator !=
a != b : nie rozne
operator <
a < cc : falsz
*********************************************************************************************
Klasa Shared - smart wskaznik z licznikiem referencji - wskaznik wspoldzielony jak shared_ptr
tworze wskaznik 's' z wartoscia 7
ile obiektow typu s : 1
tworze wskaznik 's2' z wartoscia 10
ile obiektow typu s : 1
przypisanie do powyzszego wskaznika 's2' wartosci 11 za pomoca s2.reset(11)
*s2=11
ile obiektow typu s2: 1
wywolanie funkcji foos(s2) czyli stworzenie kopi przez przeslanie argumentu
------------------z wnetrza funkcji, kopia argumentu ma wartosc: 11
------------------z wnetrza funkcji ile= 2
po wyjsciu z funkcji: ile obiektow typu s2 : 1
vector typu Shared<int> i dodane typu <int>
zaczynam pushback
byl push s
byl push s
byl push s2
byl push s
byl push s2
wyswietlam rangefor:
7 7 11 7 11
rangefor koniec
ile obiektow s : 4
ile obiektow vector[s] : 4
ile obiektow vector[s2] : 3
tworze wskaznik 'ch' typu <char> z wartoscia 8
ile obiektow typu ch: 1
ile obiektow typu s2 : 3
zad 2
Ring Buffer
Napisać implementację RingBuffer:
RingBuffer - potrafi przechowywać maksymalnie N elementów
https://en.wikipedia.org/wiki/Circular_buffer
RingBuffer ma być kontenerem STL
ma wspierać range for oraz podstawowe algorytmy STL'a
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
template<typename T,int N>
class Ringbuffer
{
typename std::vector<T>::iterator it;
int licz=0;
public:
std::vector<T> myvec;
Ringbuffer()
{
myvec.assign(N,0);
it=myvec.begin();
}
typename std::vector<T>::iterator begin()
{
return myvec.begin();
}
typename std::vector<T>::iterator end()
{
myvec.end();
}
void push(T arg1 )
{
if(licz==N)
{
std::rotate(myvec.begin(), myvec.begin() + 1, myvec.end());
licz-=1;
}
*(it+licz)=arg1;
licz+=1;
}
T pop()
{
if (licz==0)
return 0;
T ret=*(it);
std::rotate(myvec.begin(), myvec.begin() + 1, myvec.end());
licz-=1;
*(it+N-1)=0;
return ret;
}
void show()
{
for (auto element : myvec)
cout<<element<<",";
cout<<endl;
}
};
int main ()
{
cout << "tworze Ringbuffer typu int o wielkosci 10\n";
Ringbuffer<int,10> ring;
cout << "pushuje kolejno 10,11,12,13,14,15\n";
ring.push(10);
ring.push(11);
ring.push(12);
ring.push(13);
ring.push(14);
ring.push(15);
cout << "rangefor na vektorze z ringu: "; //prawdziwy rangefor na koncu
for (auto element : ring.myvec)
cout<<element<<",";
cout<<endl;
cout << "metoda show :";
ring.show();
cout << " pushuje 16,17,18\n";
ring.push(16);
ring.push(17);
ring.push(18);
cout << "metoda show :";
ring.show();
cout << " pushuje 19\n";
ring.push(19);
cout << "metoda show :";
ring.show();
cout << " pushuje 20\n";
ring.push(20);
cout << "metoda show :";
ring.show();
cout << " pushuje 21\n";
ring.push(21);
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout << " pushuje 96,97,98\n";
ring.push(96);
ring.push(97);
ring.push(98);
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout << " pushuje 80,81,82,83,94,85\n";
ring.push(80);
ring.push(81);
ring.push(82);
ring.push(83);
ring.push(84);
ring.push(85);
cout << "metoda show :";
ring.show();
cout << " pushuje 86,87,88,89,90,91\n";
ring.push(86);
ring.push(87);
ring.push(88);
ring.push(89);
ring.push(90);
ring.push(91);
cout << "metoda show :";
ring.show();
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout<<"metoda pop\n"<<ring.pop()<<endl;
cout << "metoda show :";
ring.show();
cout << "_____________range_for______________\n";
for (const auto& element: ring)
cout<<element<<",";
cout<<endl;
cout << "_____________range_for______________\n";
return 0;
}
wynik programu:
tworze Ringbuffer typu int o wielkosci 10
pushuje kolejno 10,11,12,13,14,15
rangefor na vektorze z ringu: 10,11,12,13,14,15,0,0,0,0,
metoda show :10,11,12,13,14,15,0,0,0,0,
pushuje 16,17,18
metoda show :10,11,12,13,14,15,16,17,18,0,
pushuje 19
metoda show :10,11,12,13,14,15,16,17,18,19,
pushuje 20
metoda show :11,12,13,14,15,16,17,18,19,20,
pushuje 21
metoda show :12,13,14,15,16,17,18,19,20,21,
metoda pop
12
metoda show :13,14,15,16,17,18,19,20,21,0,
metoda pop
13
metoda show :14,15,16,17,18,19,20,21,0,0,
pushuje 96,97,98
metoda show :15,16,17,18,19,20,21,96,97,98,
metoda pop
15
metoda show :16,17,18,19,20,21,96,97,98,0,
metoda pop
16
metoda show :17,18,19,20,21,96,97,98,0,0,
metoda pop
17
metoda pop
18
metoda show :19,20,21,96,97,98,0,0,0,0,
metoda pop
19
metoda pop
20
metoda pop
21
metoda pop
96
metoda pop
97
metoda pop
98
metoda pop
0
metoda show :0,0,0,0,0,0,0,0,0,0,
pushuje 80,81,82,83,94,85
metoda show :80,81,82,83,84,85,0,0,0,0,
pushuje 86,87,88,89,90,91
metoda show :82,83,84,85,86,87,88,89,90,91,
metoda pop
82
metoda pop
83
metoda show :84,85,86,87,88,89,90,91,0,0,
_____________range_for______________
84,85,86,87,88,89,90,91,0,0,
_____________range_for______________
zad 3
Matrix<M,N,T>
Napisać implementację:
posiada operatory:
dodawania macierzy (+)
mnożenia macierzy (+)
dodawania skalara do macierzy (+)
mnożenia macierzy przez skalar (+)
dostarcza konstruktory:
domyślny
kopiujący (+)
przesuwający*
Zadanie dodatkowe: gdzie występuje (+) implementacja ma działać dla typu T1 który jest konwertowalny do typu T
#include<iostream>
#include<vector>
using namespace std;
template <int N,int M,typename T>
struct Matrix
{
std::vector<vector<T> > matryca {N,vector<T>(M)}; //macierz Vektorow o wielkosci NxM wypelniona zerami
std::vector<typename vector<T>::iterator> iteratory; //vektor przechowujacy iteratory typu vector<T>
typename vector<vector<T> >::iterator it=matryca.begin(); //iterator 1 wymiaru macierzy, vektor na vektor
Matrix(){ //konstruktor wypwlniajacy vektor iteratorw 2 wymiaru
if(N==0 && M==0)
cout<<"N=0 i M=0, nie moge stworzyc"<<endl;
else
for(int i=0;i<N;i++)
iteratory.push_back((*(it+i)).begin());
}
template <int N1,int M1,typename T1>
Matrix (const Matrix<N1,M1,T1>& another){ //konstruktor kopiujacy
if( std::is_convertible<T,T1>::value )
{
if(N1<=N && M1<=M )
{
for(int i=0; i<N1;i++)
{
for( int j=0;j<M1;j++)
{
matryca[i][j]=another.matryca[i][j];
}
}
}
else
cout<<"za duza tablica do skopiowania"<<endl;
}
else
cout<<"niekonwertowalny TYP danych"<<endl;
}
template <int N1,int M1,typename T1>
Matrix (Matrix<N1,M1,T1>&& another){ //konstruktor przenoszacy
if( std::is_convertible<T,T1>::value )
{
if(N1<=N && M1<=M )
{
for(int i=0; i<N1;i++)
{
for( int j=0;j<M1;j++)
{
matryca[i][j]=another.matryca[i][j];
another.matryca[i][j]=0;
}
}
}
else
cout<<"za duza tablica do skopiowania"<<endl;
}
else
cout<<"niekonwertowalny TYP danych"<<endl;
}
template <int N1,int M1,typename T1>
void operator +(Matrix<N1,M1,T1> another) //dodawanie macierzy
{
if( std::is_convertible<T,T1>::value )
{
if(N1<=N && M1<=M )
{
for(int i=0; i<N1;i++)
{
for( int j=0;j<M1;j++)
{
matryca[i][j]+=another.matryca[i][j];
}
}
}
else
cout<<"za duza tablica do dodania"<<endl;
}
else
cout<<"niekonwertowalny TYP danych"<<endl;
}
template <typename T1>
void operator +(T1 another) //dodawanie skalara do macierzy
{
if( std::is_convertible<T,T1>::value )
{
for(int i=0; i<N;i++)
{
for( int j=0;j<M;j++)
{
matryca[i][j]+=another;
}
}
}
else
cout<<"niekonwertowalny TYP danych"<<endl;
}
template <int N1,int M1,typename T1>
void operator *(Matrix<N1,M1,T1> another) //Mnozenie macierzy
{
if( std::is_convertible<T,T1>::value )
{
if(N1<=N && M1<=M )
{
for(int i=0; i<N1;i++)
{
for( int j=0;j<M1;j++)
{
matryca[i][j]*=another.matryca[i][j];
}
}
}
else
cout<<"za duza tablica do dodania"<<endl;
}
else
cout<<"niekonwertowalny TYP danych"<<endl;
}
template <typename T1>
void operator *(T1 another) //Mnozenie skalara przez macierz
{
if( std::is_convertible<T,T1>::value )
{
for(int i=0; i<N;i++)
{
for( int j=0;j<M;j++)
{
matryca[i][j]*=another;
}
}
}
else
cout<<"niekonwertowalny TYP danych"<<endl;
}
T operator[] (int n){ //przeciazony operator [],podajesz zbiorowy index zwraca wartosc
int rz=(int)(n/M);
int nr=n-(rz*M);
return *(iteratory[rz]+nr);
}
friend ostream& operator<< (ostream& out, const Matrix& obj) { //przeciazony operator <<
out<<"start---------"<<endl;
out<<"Twoja matryca: "<<endl;
for(int i=0; i<N;i++)
{
for( int j=0;j<M;j++)
{
out<<obj.matryca[i][j];
out<<",";
}
out<<endl;
}
out<<"end-----------"<<endl;
return out;
}
};
int main()
{
cout<<endl<<"Implementacja Matrix<N, M, T> gdzie N i M wielkosc, T - typ"<<endl<<endl;
cout<<"Stworzenie Matrix<3,4,int> aaa i wypelnia danymi."<<endl<<endl;
Matrix<3,4,int> aaa; //stworz macierz vektorw o wielkosci 3x3
aaa.matryca[0][0]=10;
aaa.matryca[0][1]=11;
aaa.matryca[0][2]=12;
aaa.matryca[0][3]=77;
aaa.matryca[1][0]=13;
aaa.matryca[1][1]=14;
aaa.matryca[1][2]=15;
aaa.matryca[1][3]=88;
aaa.matryca[2][0]=16;
aaa.matryca[2][1]=17;
aaa.matryca[2][2]=18;
aaa.matryca[2][3]=99;
cout<<"Polecenie: 'cout << aaa' przeciazony << wynik:"<<endl; // operator <<
cout<<aaa<<endl;
cout<<"Polecenie: 'cout << aaa[4]' przeciazony(jeden index na cala macierz) [] wynik:"<<endl; //operator []
cout<<(aaa[4])<<endl;;
cout<<"end-----------"<<endl<<endl;
cout<<"Stworzenie Matrix<4,5,int> bb(aaa) za pomoca konstruktora kopiujacego."<<endl<<endl;;
Matrix<4,5,double> bb(aaa); //konstruktor kopiujacy (tylko do wiekszej)
cout<<"Stworzona konstruktorem kopiujacym bb wyglada tak:"<<endl;
cout<<bb<<endl<<endl; //wyswietl
cout<<"Stworzenie Matrix<4,5,int> cc(aaa) za pomoca konstruktora przenoszacego."<<endl<<endl;;
Matrix<4,5,double> cc(move(aaa)); //konstruktor kopiujacy (tylko do wiekszej)
cout<<"Stworzona konstruktorem przenoszacym cc wyglada tak:"<<endl;
cout<<cc<<endl<<endl; //wyswietl
cout<<"Po przeniesieniu aaa wyglada tak:"<<endl;
cout<<aaa<<endl<<endl; //wyswietl
cout<<"Dodaj bb+cc, przeciazony + , wynik zapisz w bb."<<endl<<endl;
bb+cc;
cout<<"Po dodaniu Twoje bb wyglada tak:"<<endl;
cout<<bb<<endl<<endl; //wyswietl
cout<<"Dodaj skalar 5 do bb, przeciazony + , wynik zapisz w bb."<<endl<<endl;
bb+5;
cout<<"Po dodaniu Twoje bb wyglada tak:"<<endl;
cout<<bb<<endl<<endl; //wyswietl
cout<<"przemnoz bb*cc, przeciazony * , wynik zapisz w bb."<<endl<<endl;
bb*cc;
cout<<"Po mnozeniu Twoje bb wyglada tak:"<<endl;
cout<<bb<<endl<<endl; //wyswietl
cout<<"przemnoz skalar 2 przez bb, przeciazony * , wynik zapisz w bb."<<endl<<endl;
bb*2;
cout<<"Po mnozeniu Twoje bb wyglada tak:"<<endl;
cout<<bb<<endl<<endl; //wyswietl
return 0;
}
wynik programu:
Implementacja Matrix<N, M, T> gdzie N i M wielkosc, T - typ
Stworzenie Matrix<3,4,int> aaa i wypelnia danymi.
Polecenie: 'cout << aaa' przeciazony << wynik:
start---------
Twoja matryca:
10,11,12,77,
13,14,15,88,
16,17,18,99,
end-----------
Polecenie: 'cout << aaa[4]' przeciazony(jeden index na cala macierz) [] wynik:
13
end-----------
Stworzenie Matrix<4,5,int> bb(aaa) za pomoca konstruktora kopiujacego.
Stworzona konstruktorem kopiujacym bb wyglada tak:
start---------
Twoja matryca:
10,11,12,77,0,
13,14,15,88,0,
16,17,18,99,0,
0,0,0,0,0,
end-----------
Stworzenie Matrix<4,5,int> cc(aaa) za pomoca konstruktora przenoszacego.
Stworzona konstruktorem przenoszacym cc wyglada tak:
start---------
Twoja matryca:
10,11,12,77,0,
13,14,15,88,0,
16,17,18,99,0,
0,0,0,0,0,
end-----------
Po przeniesieniu aaa wyglada tak:
start---------
Twoja matryca:
0,0,0,0,
0,0,0,0,
0,0,0,0,
end-----------
Dodaj bb+cc, przeciazony + , wynik zapisz w bb.
Po dodaniu Twoje bb wyglada tak:
start---------
Twoja matryca:
20,22,24,154,0,
26,28,30,176,0,
32,34,36,198,0,
0,0,0,0,0,
end-----------
Dodaj skalar 5 do bb, przeciazony + , wynik zapisz w bb.
Po dodaniu Twoje bb wyglada tak:
start---------
Twoja matryca:
25,27,29,159,5,
31,33,35,181,5,
37,39,41,203,5,
5,5,5,5,5,
end-----------
przemnoz bb*cc, przeciazony * , wynik zapisz w bb.
Po mnozeniu Twoje bb wyglada tak:
start---------
Twoja matryca:
250,297,348,12243,0,
403,462,525,15928,0,
592,663,738,20097,0,
0,0,0,0,0,
end-----------
przemnoz skalar 2 przez bb, przeciazony * , wynik zapisz w bb.
Po mnozeniu Twoje bb wyglada tak:
start---------
Twoja matryca:
500,594,696,24486,0,
806,924,1050,31856,0,
1184,1326,1476,40194,0,
0,0,0,0,0,
end-----------
Uwagi:
1) Skrócony sposób tworzenia vektora vektorów
std::vector<vector<T> > matryca {N,vector<T>(M)};
2) Jeśli chcesz stworzyć iterator na vektor ale nieznanego typu <T> (tu iterator 1 wymiaru matrycy)
dodaj typename:
typename vector<vector<T> >::iterator it=matryca.begin();
jesli chcesz stworzyć vektor iteratorow (iterator dla typu vektor<T> )
std::vector<typename vector<T>::iterator> iteratory;
stworzenie i przypisanie do tego vektora iteratorów (dlatego.begin) wewnętrznych vektorów- 2 wymiar macierzy
w konstruktorze:
for(int i=0;i<N;i++)
iteratory.push_back( (*(it+i)).begin() );
3) Konstruktor kopiujący musi zawierac swoj template
template <int N1,int M1,typename T1>
Matrix (const Matrix<N1,M1,T1>& another){
4) Przeciążony operator << ma taka konstrukcje
friend ostream& operator<< (ostream& out, const Matrix& obj)
5) Jeśli chcesz sprawdzić czy typy są konwertowalne
std::is_convertible<T,T1>::value