Matrici rare si ceva POO

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
Post Reply
Ilumar58
Junior
Junior
Posts: 28
Joined: 26 Oct 2011, 13:15
Judet: Galaţi

Matrici rare si ceva POO

Post by Ilumar58 » 08 Mar 2012, 12:46

Salutare comunitate :whorship:
Incerc sa implementez cateva operatii pe matrici rare de numere complexe: suma, inmultire, determinant si inversa si am ajuns la un impas cu implementarea. Am decis sa fac o matrice-lista cu putinele elemente diferite de 0 legate intre ele. Am ceva dificultati la suma in privinta adunarii elementelor diferite de 0 cu cele egale cu 0, mai specific cele egale cu 0 fiindca nu sunt propriu-zis puse intr-o structura de matrice dupa cum o sa vedeti in cod. Ma gandeam sa introduc o constanta cu valoarea 0 in else-ul care l-am lasat gol si sa adun cu elementele din ambele matrici unde le intalnesc dar nu mi-am infasurat creierul in jurul ideiei inca si ma intrebam(de fapt va intreb) daca pot face ceva mai elegant fiindca presimt ca o sa imi dea ceva dureri de cap forma asta de implementare la determinant si inversa. Daca nu, ma gandeam sa fac precum Wile E Coyote si sa revin la plansa, in sensul ca o sa implementez o clasa de numere complexe, si o clasa de matrici rare cu o data matrice de tip numere complexe si plec de acolo. A si o alta intrebare...prima data cand am vrut sa fac functia membru SumaMatrici am vrut sa aiba doar 2 parametri si primul obiect care apeleaza functia sa fie cel modificat (am incercat cu pointerul this dar am aflat repede ca nu ma pot juca asa cum vreau cu el, imi dadea eroare -anchorism- si m-am prins repede ce faceam gresit, vroiam sa ii modific adresa :roll: :D )...anyway nu is copt cu poo-ul inca si ma intrebam cum pot transforma functia aia intr-o functie ce imi returneaza this - MRare& MRare::SumaMatrici(param1,param2){....return this} si sa imi functioneze codul de acolo. Pff ce roman am scris aici, hai sa va arat si codul:

Code: Select all

#include<iostream>
using namespace std;
const short nMax = 6;

class MRare
{
	int *valReal,*valImaginar,linie,coloana;
	MRare *urm;
public:
	MRare();
	~MRare();
	void CitesteMatrice(MRare*&);
	void AfiseazaMatrice(MRare*);
	short comparaPozitie(MRare*);
	void SumaMatrici(MRare*&,MRare*,MRare*);
	 
};

MRare::MRare()
{	
  valReal = new int; valImaginar = new int;
}


MRare::~MRare()
{ delete valReal; delete valImaginar;
}


short MRare::comparaPozitie(MRare* M)
{
	short rez;
	if(linie < M->linie) rez = -1;
	if(linie == M->linie && coloana < M->coloana) rez = -1;
	if(linie == M->linie && coloana == M->coloana) rez = 0;
	if(linie > M->linie) rez = 1;
	if(linie == M->linie && coloana > M->coloana) rez = 1;
	return rez;
}



void MRare::CitesteMatrice(MRare*& M)
{int nr;
  cout<<"Introduceti numaul de elemente diferite de 0 ";cin>>nr;cout<<"\n\n";
  MRare *man ,*q;M = NULL;
 for(int begin = 1; begin <= nr; begin++)
 {
   cout<<"Elementul "<<begin<<"\n\n";
   cout<<"Introdu linia elementului: "; cin>>linie;cout<<"\n\n";
   cout<<"Introdu coloana elementului: "; cin>>coloana;cout<<"\n\n";
   if(linie>nMax || coloana>nMax || linie<1 || coloana<1)
	   {cout<<"Eroare de input! Reintrodu!\n"; continue;}
   q = new MRare;
   cout<<"Introdu valoarea reala a elementului: "; cin>>*valReal;cout<<"\n\n";
   cout<<"Introdu valoarea imaginara a elementului: "; cin>>*valImaginar;cout<<"\n\n";
   cout<<"Elementul de pe linia "<<linie<<"|coloana "<<coloana<<"= "<<*valReal<<"+i"<<*valImaginar;cout<<"\n\n";
   
   q->linie = linie; q->coloana = coloana; *q->valReal = *valReal; *q->valImaginar = *valImaginar;
   if(M == NULL) {q->urm = NULL; M = q;}
   else
	   if((q->comparaPozitie(M))<0)
	   {
		   q->urm = M;
		   M = q;
	   }
	   else
	   {
		   man = M;
		   while(man->urm && man->comparaPozitie(q)<0)
			   man = man->urm;
		   if(man->urm)
		   {
			   q->urm = man->urm;
			   man->urm = q;
		   }
		   else
		   {
			   q->urm = NULL;
			   man->urm = q;
		   }
	   }
 }
}


void MRare::AfiseazaMatrice(MRare* M)
{
	int i,j,elem1,elem2;
	for( i=1;i<=nMax;i++)
	{
		cout<<"\n";
	for( j=1;j<=nMax;j++)
		{
			elem1 = 0; elem2 = 0;
	if( M && i==M->linie && j==M->coloana)
	{
		elem1 = *M->valReal; elem2 = *M->valImaginar;
		M = M->urm;
	}
	cout<<elem1<<"+i"<<elem2<<"   ";
}
}
	cout<<"\n";
}


void MRare::SumaMatrici(MRare*& R,MRare* M1,MRare* M2)
{MRare *prim1 = M1,*prim2,*q,*man; R = NULL; 
for(;prim1!=NULL;prim1 = prim1->urm)
{
	prim2 = M2;
	while(prim2 != NULL)
	{
	if(prim1->comparaPozitie(prim2) == 0)
		{
			q = new MRare;
			
			q->linie = prim1->linie; q->coloana = prim1->coloana;
			*q->valReal =*prim1->valReal + *prim2->valReal;
			*q->valImaginar =*prim1->valImaginar + *prim2->valImaginar;
			if(R == NULL)
			{
				q->urm = NULL;
				R = q;man = R;
			}
			else
			{								
				q->urm = NULL; 
				man->urm = q;
				man = man->urm;
			}
				
	
		}
	else
	{
          .................................
	}
	
		prim2 = prim2->urm;
	
	}
	
}
}




int main()
{
	MRare *A,*B,*Rezultat; A = new MRare;B = new MRare;Rezultat = new MRare;
	A->CitesteMatrice(A);
	A->AfiseazaMatrice(A);
	B->CitesteMatrice(B);
	B->AfiseazaMatrice(B);
	Rezultat->SumaMatrici(Rezultat,A,B);
	Rezultat->AfiseazaMatrice(Rezultat);

	system("pause");
}









User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Matrici rare si ceva POO

Post by bu7ch3r » 08 Mar 2012, 14:56

Care-i scopul in ceea ce ai scris tu? Adik pentru o matrice rara se pune problema sa o pastrezi in memorie pe un spatiu cat mai mic, tu ai pointeri si obiecte care ocupa memorie cat pentru 3 matrici :D
Normal trebuie sa abstractizezi totul intr-un singur obiect asa cum ai intuit. Nu e chiar optim sa tot faci obiecte si sa le legi intre ele ca si cum ar fi structuri, pe langa asta pierzi mult timp la access.
Acum clasa aia MRare e practic clasa ElementDinMatriceRar :)

Code: Select all

class MatriceRara
{
//private: //:P
int m_nRand[100]; //poti sa-i faci pointeri si sa-i aloci in constructor ceva de genu MatriceRara(nRand, nColoana) dar asa s-ar putea sa/sigur sa aloci mai multa memorie pentru valori decat iti trebuie 
int m_nColoana[100];
m_REAL[100];//sau poti sa-i realoci pe toti ori de cate ori pui un element nou dar  trebuie sa stii tot timpul cate elemente ai
//REAL e o structura care are doi inti : imaginar si real etc :))
int m_nSize;
}

MatriceRara::AddElement(nRand, nColoana, RValoare)
{
//realoci memorie 
*(m_nRand + m_nSize) = nRand;   //m_nRand[m_nSize] = nRand;
*(m_nColoana + m_nSize) = nColoana; 
(*(m_REAL + m_nSize)).real = RValoare.real;//sau il faci si pe asta obiect nu structura si supraincarci operatorul = sa faca frumos si o sa poti sa faci apoi m_REAL = RValoare
(*(m_REAL + m_nSize)).imaginar = RValoare.imagina;  //m_REAL[m_nSize].imagina = RValoare.imaginara;
m_nSize++;
}
Nu inteleg schema cu pointer-ul la int :)) valReal si valImaginar :-??

P.S.L.E:
Exemplu asta e cel mai simplu posibil dar sunt o gramada de modalitati de a stoca matrici rare unele mai bune altele mai nebune, depinde de cum sunt imprastiate 0-urile prin matrice;)
Cu stima,
Lupu Claudiu

Ilumar58
Junior
Junior
Posts: 28
Joined: 26 Oct 2011, 13:15
Judet: Galaţi

Re: Matrici rare si ceva POO

Post by Ilumar58 » 08 Mar 2012, 17:05

Banuiam ca nu e ok sa fac un comportament asemenea structurilor dar cum spuneam abia am intrat in oop. O sa ma uit peste codul tau sa vad ce fac mai departe.
Multumesc!

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Matrici rare si ceva POO

Post by bu7ch3r » 08 Mar 2012, 17:46

Nu l-as numi chiar cod pe ala, e ceva de unde sa pornesti. Mai ai de supraincarcat operatorii +, * etc :)

Poti sa-ti faci chiar si clasa CReal, este deja implementata in msdn din cate imi aduc eu aminte :)
Cu stima,
Lupu Claudiu

User avatar
mihk
Junior
Junior
Posts: 39
Joined: 03 Jul 2009, 14:51

Re: Matrici rare si ceva POO

Post by mihk » 09 Mar 2012, 00:11

Nu am pretentia ca asta e solutia la problema ta.
Sper totusi sa te ajute.

Code: Select all


#include <map>
#include <complex>
#include <iostream>


template<typename T, size_t col = 4>
class column
{
public:	
	typedef std::complex<T> complex;
	typedef std::map<size_t, complex> Map;
	

	column(){};

	column(const column& c)
	{
		*this=c;
	};

	column& operator=(const column& c)
	{
		if(this!=&c)
		{
			m_cols = c.m_cols;			
		}
		return *this;
	};

	const complex* operator[](size_t pos) const
	{
		if(pos >= col)
			throw "coloana in afara matricii";

		Map::const_iterator i = m_cols.find(pos);
		if( i == m_cols.end() ) return 0;
		return &(i->second);
	};

	complex* operator[](size_t pos)
	{
		if(pos >= col)
			throw "coloana in afara matricii";

		Map::iterator i = m_cols.find(pos);
		if( i == m_cols.end() ) return 0;
		return &(i->second);
	};

	void add(size_t pos, const complex& c)
	{
		if(pos >= col)
			throw "coloana in afara matricii";

		m_cols[ pos ] = c;
	};

	void remove(size_t pos)
	{
		if(pos >= col)
			throw "coloana in afara matricii";

		m_cols.erase( pos );
	};

	bool empty()const
	{
		return m_cols.empty();
	};

	bool clear()
	{
		m_cols.clear();
	};
	
private:
	Map m_cols;
	
	
};



template<typename T, size_t row=4, size_t col=4>
class matrix
{
public:
	typedef typename column<T, col>::complex complex;
	typedef std::map<size_t, column<T, col> > Map;

	matrix(){};

	matrix(const matrix& m)
	{
		*this=m;
	};

	matrix& operator=(const matrix& m)
	{		
		if(this!=&m)
		{
			m_rows = m.m_rows;
		}
		return *this;
	};

	column<T, col>& operator[](size_t pos)
	{
		if(pos >= row)
			throw "rand in afara matricii";

		return m_rows[pos];
	};

	void add(size_t mrow, size_t mcol, const complex& c)
	{
		if(mrow >= row)
			throw "rand in afara matricii";

		(*this)[mrow].add(mcol, c);
	};

	void remove(size_t mrow, size_t mcol)
	{
		if(mrow >= row)
			throw "rand in afara matricii";

		(*this)[mrow].remove(mcol);
	};

	bool empty()
	{
		return m_rows.empty();
	};

	void clear()
	{
		m_rows.clear();
	};

	void operator+=(const matrix<T, row, col>& m)
	{
		for(size_t i=0; i<row; ++i)
		{
			for(size_t j=0; j<col; ++j)
			{
				complex* left = (*this)[i][j];
				complex* right = const_cast<matrix<T, row, col>&>(m)[i][j];

				if(left && right)
				{
					*left += *right;
				}
				else if(!left && right)
				{
					(*this)[i].add(j, *right);
				}								
			}
		}
	};

	void show()
	{
		std::cout << "\nMATRIX" << std::endl;
		for(size_t i=0; i<row; ++i)
		{
			std::cout << "row[" << i << "]=\t";
			for(size_t j=0; j<col; ++j)
			{
				complex* left = (*this)[i][j];
				if( !left )
					std::cout << " [0, 0] ";
				else
					std::cout << " [" << left->real() << ", " << left->imag() << "] ";
			}
			std::cout << std::endl;
		}
	};

private:
	Map m_rows;
	
};


int main()
{

	matrix<float, 3, 5> M;
	matrix<float, 3, 5> N;
	M.add(0, 0, std::complex<float>(-1, -1));
	N.add(0, 0, std::complex<float>(-1, -1));

	M += N;

	M.show();



	return 0;
}
Caut profesor.

Ilumar58
Junior
Junior
Posts: 28
Joined: 26 Oct 2011, 13:15
Judet: Galaţi

Re: Matrici rare si ceva POO

Post by Ilumar58 » 09 Mar 2012, 01:51

Multumesc pentru raspuns @mihk, ma voi uita mai atent peste codul tau dupa ce trec peste STL si template-uri in general!

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Matrici rare si ceva POO

Post by cristianamarie » 09 Mar 2012, 09:02

Poti sa tii si un std::vector (std::list), care tine linia/coloana/valoarea cind e nenula.
Desi poate cel mai bine ar fi

Code: Select all

template<typename T>
struct matrix {
  typedef int LINE;
  typedef int COLUMN;
  typedef std::pair<LINE, COLUMN> POSITION;
  typedef std::map < POSITION , T > ELEMENTS;

  ELEMENTS elements;

  matrix() {}

  matrix<T>& set(LINE line, COLUMN column, const T& value) /* sau T value, daca n-are sens referinta */
  {
    elements[POSITION(line, column)] = value;
    return *this;
  }
  bool get(LINE line, COLUMN column, T& value) const {
    if(elements.find(POSITION(line, column)) == elements.end()) {
      return false; }
    return elememtns[POSITION(line, column));
  }
};
sau asa ceva.

Atunci adunarea devine
m[x1, y1] + m[x2, y2] = v1 + v2
v1 = 0 daca n-avem (x1,y1) in vector, si la fel v2

m[x1, y1] + m[x2, y2] = 0 nu exista x1,y1 nici x2,y2
m[x1, y1] + m[x2, y2] = v1 nu exista x2,y2
m[x1, y1] + m[x2, y2] = v2 nu exista x1,y1
m[x1, y1] + m[x2, y2] = v1 + v2 exista ambele
Nuclear launch detected

Post Reply