Explorați Cărți electronice
Categorii
Explorați Cărți audio
Categorii
Explorați Reviste
Categorii
Explorați Documente
Categorii
Proiect POO
Profesor coordonator:
Prep. Drd. Mihaia Dragan
Student:
Andrei Ciulpan
Andrei Buhai
Bucureti 2012
Operaii cu polinoame
Profesor coordonator:
Prep. Drd. Mihaia Dragan
Student:
Andrei Ciulpan
Andrei Buhai
Bucureti 2012
Cuprins
Introducere.........................................................................................2
Cerina problemei..............................................................................4
Codul surs.........................................................................................5
Exemplu.............................................................................................37
Bibliografie........................................................................................38
Introducere
Mult vreme C a fost limbajul preferat de programatori, n special de cei care
dezvoltau aplicaii pentru sistemele MS-DOS i WINDOWS. n ultima vreme
ns, popularitatea limbajului C++ a crescut datorit faptului c permite
programarea orientat pe obiecte (Object-Oriented Programming) - o metod de
programare folosit n prezent pentru realizarea multor aplicaii software. Ideea
programrii orientate pe obiecte (POO) a aprut n anii 60, fiind pus n
practic prin intermediul limbajelor SIMULA (1967) i SMALLTALK (1975).
Totui, aceste limbaje au avut o rspndire relativ redus, deoarece puini
programatori formai la coala limbajelor clasice procedurale din acea perioad
(FORTRAN, COBOL, PASCAL, MODULA-2, C etc.) erau dispui s
abandoneze aceste limbaje doar de dragul de a lucra obiectual. Cu toate acestea,
n anii 80, n urma acceptrii definitive a limbajului C, un colectiv condus de
Bjarne Stroustrup, un tnr cercettor de la Bell Labs, a avut ideea scrierii unui
compilator care s preia simplitatea i flexibilitatea C-ului i mecanismele de
"modelare ale limbajului SIMULA 67. Bjarne a numit acest dialect C with
Classes i, prima versiune comercial a acestuia a aprut la AT&T n 1983, cu
denumirea modificat n cea actual, C++ (sugerat de Rik Masciti, un
colaborator apropit a lui B. Stroustrup). Denumirea de C++ semnific de fapt
multiplele facilitti adugate limbajului C. Profitnd de multitudinea domeniilor
de aplicaie (de la grafica interactiv la proiectarea interfeelor utilizator i de la
exploatarea reelelor de calculatoare la tehnicile de proiectare a
compilatoarelor), printre programatori n general i printre programatorii de C
n particular, aproape imediat apar partizani ai POO-ului. De ce acest succes
extraordinar ? n primul rnd, din cauza faptului c limbajul C++ nu face nimic
altceva dect sa dea un nou avnt unuia dintre cele mai la mod limbaje ale
momentului (este vorba de C), iar n al doilea rnd din cauza faptului c aduce o
i mai mare economie de timp n procesul de dezvoltare-implementare-testare a
aplicaiilor software. n cazul limbajelor tradiionale procedurale (3GLs - 3rd
Generation Languages), algoritmul materializat ntro diagram de flux a datelor
(DFD - Data Flow Diagram), ajunge s se adapteze arhitecturii calculatorului.
Generaia a patra de limbaje (4GLs), cum se obinuiete a se denumi categoria
acestor limbaje orientate pe obiecte, urmrete adaptarea calculatorului la
obiecte.
Principii de baza:
Avantajele POO reies din definirea principalelor concepte care stau la
baza POO i anume:
Abstractizarea Este posibilitatea ca un program s ignore unele aspecte
ale informaiei pe care o manipuleaz, adic posibilitatea de a se concentra
asupra esenialului. Fiecare obiect n sistem are rolul unui actor abstract, care
poate executa aciuni, i poate modifica i comunica starea i poate comunica
cu alte obiecte din sistem fr a dezvlui cum au fost implementate acele
facilitai. Procesele, funciile sau metodele pot fi de asemenea abstracte, i n
acest caz sunt necesare o varietate de tehnici pentru a extinde abstractizarea:
ncapsularea numit i ascunderea de informaii: Asigur faptul c
obiectele nu pot schimba starea intern a altor obiecte n mod direct (ci doar
prin metode puse la dispoziie de obiectul respectiv); doar metodele proprii ale
obiectului pot accesa starea acestuia. Fiecare tip de obiect expune o interfa
pentru celelalte obiecte care specific modul cum acele obiecte pot interac iona
cu el.
Polimorfismul Este abilitatea de a procesa obiectele n mod diferit, n
funcie de tipul sau de clasa lor. Mai exact, este abilitatea de a redefini metode
pentru clasele derivate. De exemplu pentru o clas Figura putem defini o
metod arie. Dac Cerc, Dreptunghi, etc. vor extinde clasa Figura, acestea pot
redefini metoda arie.
Motenirea Organizeaz i faciliteaz polimorfismul i ncapsularea,
permind definirea i crearea unor clase specializate plecnd de la clase
(generale) deja definite - acestea pot mprti (i extinde) comportamentul lor,
fr a fi nevoie de a-l redefini. Aceasta se face de obicei prin gruparea
obiectelor n clase i prin definirea de clase ca extinderi ale unor clase existente.
Conceptul de motenire permite construirea unor clase noi, care pstreaz
caracteristicile i comportarea, deci datele i funciile membru, de la una sau
mai multe clase definite anterior, numite clase de baz, fiind posibil redefinirea
sau adugarea unor date i funcii noi. Se utilizeaz ideea: Anumite obiecte
sunt similare, dar n acelai timp diferite. O clas motenitoare a uneia sau mai
multor clase de baz se numete clas derivat. Esena motenirii const n
posibilitatea refolosirii lucrurilor care funcioneaz.
Cerina problemei
Sa se defineasc o clas generic pentru polinoame de o nedeterminat cu
coeficienti de un tip neprecizat ( parametru) , in care operatorii =,==,operatorii
aritmetici,+,-(unar si binar),* si eventual /,%, sa fie suprancarcai pentru
operaiile obijnuite cu polinoame,iar operatorul (tip) de conversie a tipurilor sa
fie supraincrcat pentru a efectua conversia unui obiect de tipul coeficienilor la
un polinom de grad 0 si invers .Sirul coeficienilor unui polinom se poate
reprezenta ca un vector(adic pointer la tipul coeficientilor) sau ca o list
simplu(dublu inlanuit la alegere).Se vor da exemple de creare si utilizare de
obiecte pentru diferite tipuri ale coeficienilor:int,float,complex(dupa definirea
acestui tip ca o clas separata),etc.
Codul surs
#include <iostream>
#include <fstream>
#include <math.h>
#include <malloc.h>
#include <complex>
#include <stdlib.h>
using namespace std;
/*
1) Sa se defineasca o clasa generica pentru polinoame de o nedeterminata
cu coeficienti de un tip neprecizat ( parametru)
vezi clasa Polinom
2)
in care operatorii
=,==,operatorii aritmetici,+,-(unar si binar),*
si eventual /,%, sa fie supraincarcati pentru operatiile obijnuite cu
polinoame,
iar operatorul (tip) de conversie a tipurilor sa fie supraincarcat
pentru a efectua conversia unui obiect de tipul coeficientilor la un
polinom de grad 0 si invers.
Sirul coeficientilor unui polinom se poate reprezenta ca un vector(adica
pointer la tipul coeficientilor)
sau ca o lista simplu(dublu inlantuita la alegere).
3)
Se vor da exemple de creare si utilizare de obiecte pentru
diferite tipuri ale coeficientilor:int,float,complex dupa definirea acestui
tip ca o clasa separata),etc.
4
*/
};//
private:
T m_coeficient;
unsigned int m_exponent;
friend class Polinom<T>;
};//class
//clasa Nod, reprezinta un nod intr-o lista dubla-inlantuita, pentru stocarea
obiectului Pereche (monom al polinomului)
template<typename T>
class Nod
{
public:
Nod(){ m_next = 0; m_prev = 0; m_pereche = 0; };
Nod* m_next; //nodul urmator
Nod* m_prev; //nodul precedent
Pereche<T>* m_pereche;//stocarea unei perechi (coef,exp)
};
m_real = 0;
m_imaginar = 0;
};
Complex(double real)
{
m_real = real;
m_imaginar = 0;
};
//constructor parametrizat
Complex(double real, double imaginar)
{
m_real=real;
m_imaginar = imaginar;
};
//constructor de copiere
Complex(const Complex& c)
{
m_real = 0.;
m_imaginar = 0.;
*this=c;
};
Complex& operator=(const Complex& c)
{
if(this!=&c)
{
7
m_real = c.m_real;
m_imaginar = c.m_imaginar;
}
return *this;
}
~Complex(){};
//supraincarcare operatorului de iesire <<, pentru afisarea la ecran a
numarului real
ostream& operator << (ostream& iesire)
{
iesire.precision(1);
iesire << "(" << m_real;
if( m_imaginar < 0 )
{
iesire << "-i*" << -1*m_imaginar;
}
else
{
iesire << "+i* " << m_imaginar;
}
iesire << ")";
return iesire ;
};
//supraincarcarea operatorului de intrare >>, pentru initializarea unui
numar complex
istream& operator >> (istream& intrare)
{
8
=" ;
Complex(m_real+numar.m_real,
};
Complex& operator+=(const Complex& numar)
{
m_real += numar.m_real;
9
m_imaginar += numar.m_imaginar;
return *this;
};
//Diferenta a 2 numere complexe z=a+bi si w=c+di este z-w=(a-c)+(b-d)i
Complex operator-(const Complex& numar)const
{
return
numar.m_imaginar);
Complex(m_real-numar.m_real,
m_imaginar-
};
m_real*numar.m_real
=
m_imaginar*numar.m_real
{
double
real=
m_imaginar*numar.m_imaginar;
double
img
m_real*numar.m_imaginar;
m_real*numar.m_real
=
m_imaginar*numar.m_real
m_real = real;
m_imaginar = img;
return *this;
};
//ridicare la putere
Complex putere(unsigned int putere)const
{
Complex rez = (*this);
unsigned int p = putere;
while(p-- > 1)
{
Complex tmp = rez * (*this);
rez = tmp;
}
return rez;
};
template<typename T>
Complex operator*(T i)const
{
return (*this) * Complex(i, 1);
};
double real()const { return m_real; };
11
=" ;
template<typename T>
bool operator!=(const Complex& c, T t)
{
return !(c == t);
}
13
template<typename T>
bool operator<(const Complex& c, T t)
{
if(c.real() < (double)t && c.imag() == 0.)
return true;
return false;
}
template<typename T>
bool operator>(const Complex& c, T t)
{
return !(c < t) && !(c == t) ;
}
template<typename T>
bool operator<=(const Complex& c, T t)
{
return c < t || c == t;
}
template<typename T>
bool operator>=(const Complex& c, T t)
{
return !(c < t);
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
class Polinom
14
{
public:
Polinom()
{
m_start = 0;
m_nod = 0;
};
~Polinom()
{
Sterge();
};
//constructor de copiere
Polinom(const Polinom<T>& p)
{
m_start = 0;
m_nod = 0;
*this = p;
};
//operator de copiere
Polinom<T>& operator=(const Polinom<T>& p)
{
if( p.m_nod == 0 ) return *this;
Sterge();
}
if(this!=&p)
{
Nod<T>* nod = p.m_start->m_next;
while(nod != 0)
{
Adauga(*(nod->m_pereche));
nod = nod->m_next;
}
}
return *this;
};
bool operator==(const Polinom<T>& p)
{
if(this==&p) return true;
Polinom
Polinom
!=
nod_t-
//avanseaza nodul
nod_p = nod_p->m_next;
nod_t = nod_t->m_next;
}
//verifica ultimul element
if(nod_p != 0 || nod_t != 0)
return false;
return true;
};
void Adauga(const Pereche<T>& p)
{
//if(p.m_coeficient == 0.) return;
//daca exista o pereche cu exponentul respectiv atunci adunam
coeficientii
Nod<T>* nod = CautaNod(p.m_exponent);
if(nod != 0)
{
Pereche<T>* gasit = nod->m_pereche;
gasit->m_coeficient += p.m_coeficient;
//sterge monomul cu coeficient zero
if(gasit->m_coeficient == (double)0.)
Verifica();
return;
}
//nu exista nici o pereche cu exponentul lui p;
//polinomul este gol ?
if(m_nod == 0)
17
{
m_start = new Nod<T>();
m_nod = new Nod<T>();
m_nod->m_pereche = new Pereche<T>(p.m_coeficient,
p.m_exponent);
m_start->m_prev = 0;
m_start->m_next = m_nod;
m_nod->m_prev = m_start;
m_nod->m_next = 0;
return ;
}
else
{
//introduce perechea in ordine crescatoare in functie de
exponent
Nod<T>* nod = m_start->m_next;
while(nod != 0)
{
Pereche<T>* pereche = nod->m_pereche;
if(p.m_exponent > pereche->m_exponent)
{
Nod<T>* adauga = new Nod<T>();
adauga->m_pereche
Pereche<T>(p.m_coeficient, p.m_exponent);
adauga->m_prev = nod->m_prev;
adauga->m_next = nod;
nod->m_prev->m_next = adauga ;
nod->m_prev = adauga;
18
new
return;
}
nod = nod->m_next;
}//while
Nod<T>* adauga = new Nod<T>();
adauga->m_pereche = new Pereche<T>(p.m_coeficient,
p.m_exponent);
adauga->m_prev = m_nod;
adauga->m_next = 0;
m_nod->m_next = adauga;
m_nod = adauga;
}
};
//verifica si sterge orice monom cu coeficientul zero
void Verifica()
{
if(m_nod == 0) return;
Nod<T>* nod = m_start->m_next;
while(nod != 0)
{
if(nod->m_pereche->m_coeficient == 0.)
{
Nod<T>* tmp = nod->m_next;
nod->m_prev->m_next = nod->m_next;
if(nod->m_next != 0)
{
nod->m_next->m_prev = nod->m_prev;
19
}
else
{
m_nod = nod->m_prev;
}
delete nod->m_pereche;
delete nod;
nod = tmp;
continue;
}
nod = nod->m_next;
}//while
};
void Sterge()
{
if(m_nod == 0) return;
while(m_nod->m_prev != 0)
{
Nod<T>* nod = m_nod;
m_nod = nod->m_prev;
delete nod->m_pereche ;
delete nod;
}
delete m_nod;
};
20
};
bool is_complex(const Complex&) const
{
return true;
}
template<typename T>
bool is_complex(const T&) const
{
return false;
}
return val;
};
Polinom<T> Suma(const Polinom<T>& p)const
{
Polinom<T> p1 = *this;
Polinom<T> p2 = p;
Polinom<T> suma;
Nod<T>* nod1 = p1.m_start->m_next;
while(nod1 != 0)
{
unsigned int exponent = nod1->m_pereche->m_exponent;
T coeficient = nod1->m_pereche->m_coeficient;
Nod<T>* nod2 = p2.CautaNod(exponent);
if(nod2 != 0)
24
{
coeficient += nod2->m_pereche->m_coeficient;
suma.Adauga(Pereche<T>(coeficient, exponent));
p2.Sterge(exponent);
}
else
{
suma.Adauga(Pereche<T>(coeficient, exponent));
}
nod1 = nod1->m_next;
}//while
Nod<T>* nod2 = p2.m_start->m_next;
while(nod2 != 0)
{
suma.Adauga( *(nod2->m_pereche) );
nod2 = nod2->m_next;
}//while
//sterge monomul cu coeficient zero
suma.Verifica();
return suma;
};//
nod2->m_pereche->m_coeficient
* (-
return produs;
};//
private:
Nod<T>* CautaNod(unsigned int exponent)
{
if(m_nod == 0) return 0;
Nod<T>* nod = m_start->m_next;
while(nod != 0)
{
//daca exista un monom cu acelasi exponent, atunci intoarce
nodul
//care contine perechea respectiva
if(nod->m_pereche->m_exponent == exponent)
{
return nod;
}
//avanseaza nodul curent
nod = nod->m_next;
}//while
return 0;
};
private:
Nod<T>* m_start;//inceputul listei
Nod<T>* m_nod;//terminarea listei
};
28
template<typename T>
istream& operator >> (istream& intrare, Polinom<T>& p)
{
cout << "\n\tCate elemente va contine polinomul ? n= ";
int m = 0;
cin >> m;
int x = 0;
if(m == 0) return intrare ;
//sterge toate elementele polinomului
p.Sterge();
//intrare de la tastatura
char line[251]="\0";
//citirea polinomului de la tastatura
while(x++ < m)
{
T coeficient(0);
unsigned int exponent = 0;
cout << "\n\tCoeficient = " ;
if( p.is_complex(T()) )
{
cin >> coeficient;
}
else
{
cin >> line;
double val = atof(line);
coeficient = (T) val;
29
}
cout << "\tExponent (intreg pozitiv) = ";
cin >> exponent ;
Pereche<T> pereche(coeficient, exponent);
p.Adauga(pereche);
cout << endl;
}//while
return intrare ;
};
template<typename T>
ostream& operator << (ostream& iesire, Polinom<T>& p)
{
p.Afiseaza(iesire);
return iesire;
};
template<typename T>
Polinom<T> operator + (const Polinom<T>& p1, const Polinom<T>& p2)
{
return p1.Suma(p2);
};//
template<typename T>
Polinom<T> operator - (const Polinom<T>& p1, const Polinom<T>& p2)
{
return p1.Diferenta(p2);
};//
template<typename T>
Polinom<T> operator * (const Polinom<T>& p1, const Polinom<T>& p2)
30
{
return p1.Produsul(p2);
};//
void main()
{
//Cerinte:
//1) definirea clasei Polinom
Polinom<int> p ;
cin >> p; //citire de la tastatura prin operator de intrare >> supraincarcat
cout << "\n\tAti introdus polinomul cu forma\n";
cout << "\n\tp=";
cout << p; //afisare prin operator de iesire << supraincarcat
{
cout << "\n\tp_2 == p -> EGAL";
}
31
else
{
cout << "\n\tp_2 != p -> DIFERIT";
}
//Operatii obisnuite cu polinoame, prin utilizare operatorilor +, - si *
cout << "\n\tPentru executarea operatiilor de adunare,scadere,inmultire se
considera 2 polinoame de forma\n";
Polinom<float> p1;
float coef1[] = {1.f, 2.f, 5.f};
unsigned int exp1[] = {3, 2, 1};
for(int i=0; i<3; i++)
{
Pereche<float> pereche(coef1[i], exp1[i]);
p1.Adauga(pereche);
}
Polinom<float> p2;
float coef2[] = {2.f, -4.f, -4.f};
unsigned int exp2[] = {2, 1, 0};
for(int j=0; j<3; j++)
{
Pereche<float> pereche(coef2[j], exp2[j]);
p2.Adauga(pereche);
}
//SUMA
cout << "\n\tSuma p1+p2=";
Polinom<float> suma = p1 + p2;
suma << cout;
//DIFERENTA
cout << "\n\tDiferenta p1-p2=";
Polinom<float> diferenta = p1 - p2;
diferenta << cout;
//PRODUS
cout << "\n\tProdusul p1*p2=";
Polinom<float> produs = p1 * p2;
produs << cout ;
//////////////////////////////////////////////////////////////////////////
cout.precision(5);
cout << fixed << produs.Valoare(x);
//////////////////////////////////////////////////////////////////////////
33
pereche(Complex(real_1[i],
imag_1[i]),
exp1[i]);
pc1.Adauga(pereche);
}
Polinom<Complex> pc2;
double real_2[] = {2.f, -4.f, -4.f};
double imag_2[] = {2.f, -4.f, -4.f};
unsigned int exp_2[] = {2, 1, 0};
for(int j=0; j<3; j++)
{
Pereche<Complex>
pereche(Complex(real_2[j],
exp_2[j]);
pc2.Adauga(pereche);
}
//afiseaza cele 2 polinoame
cout << "\n\tp1=";
pc1 << cout;
cout << "\n\tp2=";
34
imag_2[j]),
35
Exemplu
36
Bibliografie
www.wikipedia.org
www.cprogramming.com
www.learncpp.com
37