Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Laborator nr. 4
Laborator 4
#include<iostream.h>
#include<conio.h>
#include<math.h>
class patrulater{
public:
double xA,yA,xB,yB,xC,yC,xD,yD;
int valid;
patrulater(double x1,double y1,double x2,double y2,double x3,double y3,double
x4,double y4)
{
xA=x1;yA=y1;
xB=x2;yB=y2;
xC=x3;yC=y3;
xD=x4;yD=y4;
valid_1();
}
double valid_1()
{
if(((xA!=xB)||(yA!=yB))&&((xA!=xC)||(yA!=yC))&&
((xA!=xD)||(yA!=yD))&&((xB!=xC)||(yB!=yC))&&((xB!=xD)|| (yB!=yD)) && ((xC!=xD)||(yC!=yD)))
valid =1;
else
valid=0;
return valid;
}
void afis_1()
{
if (valid)
cout<<"Figura este patrulater.";
else
cout<<"Figura nu este patrulater.";
}
};
1
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
l1=sqrt(abs(l5));
l2=sqrt(abs((((xC-xB)*(xC-xB))+((yC-yB)*(yC-yB)))));
l3=sqrt(abs((((xC-xD)*(xC-xD))+((yC-yD)*(yC-yD)))));
l4=sqrt(abs((((xA-xD)*(xA-xD))+((yA-yD)*(yA-yD)))));
if ((l1==l3)&&(l2==l4))
{ validp=1; }
else
{ validp=0; }
}
else
validp=0;
return validp;
}
void afis_2()
{
if (validp)
cout<<"\nFigura este paralelogram.";
else
cout<<"\nFigura nu este paralelogram.";
}
paralelogram(double x1, double y1, double x2, double y2, double x3, double y3,
double x4, double y4): patrulater(x1,y1,x2,y2,x3,y3,x4,y4)
{ valid_2(); }
};
void main()
{
paralelogram pp(0.0,0.0,1.0,0.0,1.0,1.0,0.0,1.0);
clrscr();
cout<<"Dati cordonatele varfurilor.";
cout<<"\n xA=";cin>>pp.xA; cout<<" yA=";cin>>pp.yA;
cout<<"\n xB=";cin>>pp.xB; cout<<" yB=";cin>>pp.yB;
cout<<"\n xC=";cin>>pp.xC; cout<<" yC=";cin>>pp.yC;
cout<<"\n xD=";cin>>pp.xD; cout<<" yD=";cin>>pp.yD;
pp.valid_1();
pp.afis_1();
getch();
pp.valid_2();
pp.afis_2();
getch();
2
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
Exemplu de redefinire a unei functii care nu apeleaza functia
Exemplu 2: corespunzatoare din clasa de baza. Cele doua clase NumarComplex,
clasa de baza si NumarReal, clasa derivata au definite cate o functie
membru afisare(). In clasa derivata este redefinita fara a apela varianta din
clasa de baza.
#include <iostream.h>
#include <conio.h>
//clasa de baza NumarComplex
class NumarComplex{
protected:
double re,im;
public:
NumarComplex(double, double);
void afisare();
};
void NumarComplex::afisare()
{
cout<<"\n Numarul complex este : "<<re<<"+"<<im<<"*i";
}
void NumarReal::afisare()
{
cout<<"\n Numarul real este : "<<re;
}
void main()
{
NumarReal r = NumarReal(15);
NumarComplex z = NumarComplex(-1,3);
clrscr();
r.afisare();
z.afisare();
}
3
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
Sa se defineasca o clasa sir care sa se utilizeze la instantierea
Exemplu 3: sirurilor de caractere.
Sa se scrie un program care realizeaza urmatoarele operatii asupra
obiectelor de tip sir:
initializare
citire de siruri de caractere de la tastatura
copiere de obiecte de tip sir
atribuiri de obiecte de tip sir
afisari de siruri de caractere din compunerea obiectelor de tip sir.
Solutie:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
//enum Boolean {false,true}; //EROARE de compilare pe MinGW
class sir
{
// date membru protejate(private)
// pointer catre zona de memorie in care se pastreaza caracterele sirului
char *psir;
int lung; //lungimea sirului(numarul de caractere)
// functii membru neprotejate
public:
// constructor pt. intializarea obiectului cu pointerul
// spre sirul de caractere; acesta se pastreaza in memoria heap
sir(char *s);
//constructor care rezerva zona de memorie in memoria heap si pastreaza sirul vid
sir(int nrcar=70);
//constructor de copiere
sir(const sir&);
//destructor
~sir();
//returneaza lungimea sirului
int retlung();
//afiseaza sirul de caractere
void afsir();
//citeste un sir de caractere
int citsir();
// transfera sirul spre care pointeaza s in zona rezervata pentru sirul obiectului
// curent
// daca nu exista zona suficienta, se truncheaza sirul spre care pointeaza s si se
// returneaza valoarea false; in caz contrar se returneaza true
bool atribsir(sir *s);
};
sir::sir(char *s)
{
lung=strlen(s);
psir=new char[lung+1];
strcpy(psir,s);
}
sir::sir(int dim)
{
lung=dim;
psir=new char[lung+1];
4
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
*psir='\0';
}
sir::sir(const sir& s)
{
lung=s.lung;
psir=new char[lung+1];
strcpy(psir,s.psir);
}
sir::~sir()
{
delete psir;
}
int sir::retlung()
{
return lung;
}
void sir::afsir()
{
cout<<psir<<endl;
}
// citeste un sir de caractere de la tastatura si-l pastreaza in zona heap rezervata
// pentru obiectul curent
// returneaza 0 la sfarsit de fisier, -1 la trunchierea sirului citit, 1, altfel
int sir::citsir()
{
char temp[255];
if(gets(temp)==0) return 0;
strncpy(psir,temp,lung);
*(psir+lung)='\0';
if(strlen(temp) > lung ) return 1;
else return 1;
}
bool sir::atribsir(sir* s)
{
strncpy(psir,s->psir,lung);
if(strlen(s->psir) > lung ) return false;
else return true;
}
int main(void)
{
sir sir1=("Limbajul C++ este un C mai bun");
sir sir2=("Limbajul C++ suporta stilul de programare:\n\
- prin abstractizarea datelor;\n\
- orientata spre obiecte");
sir sir3; // instantiere fara initializare; sir3 contine sirul vid
sir sir4=sir1; //instantiere folosind constructorul de copiere
//afisarea obiectelor instantiate
cout<<"sir1 : ";sir1.afsir();
cout<<"sir2 : ";sir2.afsir();
cout<<"sir3 : ";sir3.afsir();
cout<<"sir4 : ";sir4.afsir();
//atribuiri de siruri
cout<<"========== Trunchieri ==========="<<endl;
if(sir3.atribsir(&sir1) == false) cout<<"trunchiere la atribuire"<<endl;
5
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
sir3.afsir();
if(sir3.atribsir(&sir2) == false) cout<<"trunchiere la atribuire"<<endl;
sir3.afsir();
}
Solutie:
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
class punct
{
// date membru protejate(private)
double x; //abcisa
double y; //ordonata
// functii membru neprotejate
public:
punct(double abs=0, double ord=0);
punct(const punct&);
//citeste coord. punctului
void citpunct();
//afiseaza coordonatele punctului
void afispunct();
//translatie pe directia abcisei
void xtrans(double dx);
//translatie pe directia ordonatei
void ytrans(double dy);
//returneaza abcisa
double retx();
//returneaza ordonata
double rety();
};
// constructor pentru instantierea obiectelor de tip punct; implict se instantiaza
// originea axelor
punct::punct(double abs,double ord)
{ x=abs; y=ord; }
punct::punct(const punct& p)
{ x=p.x; y=p.y; }
void punct::citpunct() // citeste coord. punctului
{
cout<<"Dati abcisa "; cin>>x;
cout<<"Dati cordonata "; cin>>y;
}
6
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
void punct::afispunct() // afiseaza coordonatele punctului
{ cout<<" ("<<x<<","<<y<<") "; }
void punct::xtrans(double dx) //translatie pe directia abcisei
{ x+=dx; }
void punct::ytrans(double dy) //translatie pe directia ordonatei
{ y+=dy; }
double punct::retx() //returneaza abcisa
{ return x; }
double punct::rety() //returneaza ordonata
{ return y; }
void main(void)
{
int m=0,n=0;
clrscr();
cout<<endl<<"Incepe generarea numerelor "<<endl;
for(;;)
{
double xaleator=rand()%100;
double yaleator=rand()%100;
punct pct(xaleator,yaleator);
n++;
if(xaleator>0 && xaleator<=80 && yaleator>0 &&yaleator<=25)
//afiseaza punctul
{
m++;
pct.afispunct();
if(m%22==0)
{
cout<<endl<<"Apasati o tasta pentru a continua ";
cout<<endl<<"Apasati zero pentru a termina "<<endl;
if(getch()=='0') break;
}
}
}
cout<<"Numarul punctelor afisate "<<m<<endl;
cout<<"Numarul punctelor generate "<<n<<endl;
cout<<"Raportul m/n "<<(double)m/n<<endl;
getch();
}
7
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
Probleme propuse:
8
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
II. Polimorfism
La cursul de Proiectarea algorimilor am invatat despre metoda backtracking
standardizat. Am observat acolo ca metoda in sine consta dintr-o unica secventa de
instructiuni care apela diferite functii care aveau intotdeauna acelasi nume, dar care se
modificau de la un program la altul.
Vom incerca acum, sa construim o clasa in care functiile init(), am_succesor() si
celelalte sa fie definite initial cu valori simple, iar apoi in clasele derivate sa poata fi
redefinite astfel incat sa rezolve fiecare problema in parte.
Dificultatea consta in faptul ca functia run() care contine algoritmul de
backtracktring va apela functiile init(), succesor(), s.a.m.d. si deci obiectul care o
foloseste trebuie sa contina si aceste functii. De aceea ele vor fi definite din start – in
clasa de baza – ca fiind virtuale, pentru ca apoi in clasele derivate sa poata fi redefinite
corespunzator fiecarei clase in parte care rezolva un anumit tip de problema. Deci, vom
aplica polimorfismul.
Initial in fisierul cu numele ‘back.cpp’, vom declara clasa bkt, in care functiile
init(), am_succesor(), e_valid(), solutie() si tipar() vor fi declarate virtuale. Deoarece
ele nu vor fi niciodata apelate in cadrul acestei clase, vor avea ‘corpul’ vid. De asemenea,
variabilele n, k, as, ev se gasesc in orice program backtracking si deci, vor fi declarate
aici.
class bkt{
public:
int st[10],n,k;
virtual void init() {}
virtual int am_succesor() { return 0; }
virtual int e_valid() { return 0; }
virtual int solutie() { return 0; }
virtual void tipar() {}
void bkt::run();
};
void bkt::run()
{
int as;
k=1;init();
while(k>0)
{
do{
}while( (as=am_succesor()) && !e_valid() );
if(as)
if(solutie()) tipar();
else
{ k++; init(); }
else k--;
9
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
}
}
Exemple de probleme care pot si rezolvate acum prin utilizarea clasei bkt, prin
polimorfism:
Generarea permutarilor
Se cere sa se genereze toate permutarile multimii {1,2,…,n}.
Exemplu 1:
Pentru a folosi clasa bkt vom defini o alta clasa, care o
mosteneste pe aceasta si care va avea functiile clasei initiale dar redefinite. Vom folosi un
constructor care va avea rolul de a citi valoarea lui n.
Fisierul ‘perm.cpp’ va defini clasa permut care va fi derivata din clasa bkt:
#include<iostream.h>
#include "back.cpp"
void permut::init()
{ st[k]=0; }
int permut::am_succesor()
{
if(st[k]<n){ st[k]++; return 1; }
else return 0;
}
int permut::e_valid()
{
for(int i=1;i<k;i++)
if(st[i]==st[k]) return 0;
return 1;
}
int permut::solutie()
{ return (k==n); }
void permut::tipar()
{
for(int i=1;i<=k;i++)
cout<<st[i]<<" ";
cout<<endl;
}
10
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
#include<iostream.h>
#include "perm.cpp"
int main()
{
permut x(3);
x.run();
}
Fisierul ‘regine.cpp’ va contine clasa dame care va fi derivata din clasa permut :
#include<math.h>
#include "perm.cpp"
int dame::e_valid()
{
for(int i=1;i<k;i++)
if( (st[i]==st[k]) || abs(st[k]-st[i])==abs(k-i) ) return 0;
return 1;
}
Iar acum pentru scrierea programului care rezolva problema celor n regine vom
construi fisierul ‘dame.cpp’ in care vom include fisierul ‘regine.cpp’ :
#include<iostream.h>
#include "regine.cpp"
int main()
{
dame x(8);
x.run();
}
11
Programare orientata pe obiecte – limbajul C++/Java
Laborator nr. 4
2. Pornind de la clasa de baza bkt (din fisierul “back.cpp”), si clasa derivata permut (din
fisierul “perm.cpp”), sa se implementeze, prin polimorfism clasa virtuala cuvinte pentru
a rezolva urmatoarea problema: Se da o multime alcatuita din n litere distincte. Se cer
toate cuvintele care se pot forma cu ele, astfel incat fiecare cuvant sa contina n litere
distincte.
Exemplu: Daca avem multimea {a,b,c}, atunci vom avea cuvintele: abc, acb, bac, bca,
cab, cba.
4. Pornind de la clasa de baza bkt (din fisierul “back.cpp”), si clasa derivata permut (din
fisierul “perm.cpp”), sa se implementeze, prin polimorfism clasa virtuala numar pentru
a rezolva urmatoarea problema: Sa se descompuna un numar natural in toate modurile
posibile, ca suma de p numere naturale nenule, distincte. Solutiile care difera doar prin
ordinea termenilor nu se vor considera disctincte. Exemplu: Pentru n=10 si p=3 se obtin
solutiile: (1, 2, 7), (1, 3, 6), (1, 4,5), (2, 3, 5).
12