Klasa wielomianu

0

Poszukuję programu (gdyż sam już nie zdążę go napisać, a wcześniej nauczyć się odpowiednich rzeczy) lub gruntownej pomocy w jego napisaniu.
Chodzi o napisanie klasy modelującej wielomian jednej zmiennej. Ma być to zrealizowane w "czystym C", ale oczywiście nie pogardzę programem, pomocą w języku C++.
Ponadto klasa ma zawierać:

  • dynamiczny rozmiar tablicy, zależny od stopnia;
  • odpowiednie konstruktory;
  • przeładowane operatory *, +, -;
  • dostęp do współczynników przez operator [ ].

Będę wdzięczny za KAŻDĄ pomoc, za każdą, nawet najmniejszą, część programu lub wskazówki do nich. No i jeszcze chciałem zaznaczyć, że termin oddania programu mam dzisiaj (16.02.2008) do godz. 24. Mogę dzięki niemu uzyskać lub nie zaliczenie...
Bardzo proszę o pomoc!

0
Pyku napisał(a)

klasy modelującej wielomian jednej zmiennej. Ma być to zrealizowane w "czystym C", ale oczywiście nie pogardzę programem, pomocą w języku C++

w C nie ma klas.
tylko w C++ sa.
zdecyduj sie..

0

Taka była treść zadania... widocznie chodzi o strukturę. Ja na prawdę nie znam się na tym zbytnio. Potrafię pisać tylko proste programy, a z klasami, strukturami w C/C++ nigdy nic wspólnego nie miałem...

0

Bardzo proszę o cokolwiek, chociażby o samą definicję struktury, o przełądowane operatory + i - (to chyba też stosunkowo proste)... no cokolwiek... każdy punkt z tego zadania jest dla mnie na wagę złota, a mam bardzo mało czasu...

0

Z reguły nie daję kodu, ale niech ci będzie. Poza tym taki topic już chyba jest bo kiedyś to już wklejałem. Nie gwarantuję poprawności mnożenia i dzielenia. Aha i wywal z kodu <constream> i operacje zmiany kolory przy wyświetlaniu, bo pewnie nie masz tej biblioteki.

#include <iostream>
#include <iomanip>
#include <vector>
#include <cstdlib>
#include <constream>

using namespace std;
using namespace conio;

#ifndef _wielomian_hpp_
#define _wielomian_hpp_

namespace dx 
{

	//-----------------------------------------------------------------------------------------------
	
	class wielomian {
		friend ostream &operator<<(ostream&, wielomian);
		friend istream &operator>>(istream&, wielomian&);
		friend wielomian operator+(wielomian, wielomian);
		friend wielomian operator-(wielomian, wielomian);
		friend wielomian operator*(wielomian, wielomian);
		friend wielomian operator/(wielomian, wielomian);
		friend wielomian operator%(wielomian, wielomian);
		
		
		void wypelnij_zerami(int);
		void usun_zb_zera();
		
		vector<double> wspol;
			
	public:	
		// konstruktory: zwyk│e i kopjuj╣cy
		
		// tworzy wielomian zerowy
		wielomian() {}
		
		// tworzy wielomian o stopniu podanym w pierwszym parametrze i wspˇ│czynnikach w drugim (domyťlnie 0)
		wielomian(int, int=0);
		
		// tworzy wielomian z jednej liczby rzeczywistej (konstruktor konwertuj╣cy na typ double)
		wielomian(double);
		
		// tworzy wielomian z tablicy elementˇw typu double o d│ugoťci podanej w drugim parametrze
		wielomian(double*, int);
		
		// konstruktor kopjuj╣cy
		wielomian(const vector<double> &);
		
		
		// prze│adowane opeartory
		// operator() zwraca wartoťŠ wielomianu
		// dla liczby podanej w parametrze
		inline double operator()(double);
		
		// operaotor[] zwraca wspˇ│czynnik o podanym
		// indeksie, mo┐na za jego pomoc╣ wstawiŠ nowy wspˇ│czynnik
		inline double &operator[](unsigned);
		
		// zwraca prawdŕ jeťli wielomian jest nie stopnia
		// jest stopnia zerowego i fa│sz w przeciwnym wypadku
		inline operator bool();
		
		// zwraca stopie˝ wielomianu
		inline int st();
		
		// dodaje do obiektu inny wielomian i zwraca *this
		inline wielomian operator+=(wielomian);
		
		// odejmuje od obiektu inny wielomian i zwraca *this
		inline wielomian operator-=(wielomian);
		
		// mno┐y obiekt przez inny wielomian i zwraca *this
		inline wielomian operator*=(wielomian);
		
		// dzieli (dzielenie ca│kowite) obiekt przez inny wielomian i zwraca *this
		inline wielomian operator/=(wielomian);
		
		// dzieli obiekt przez inny wielomian i zwraca resztŕ z dzielenia w *this
		inline wielomian operator%=(wielomian);
	};
	
	//----------------------------------
	
	wielomian::wielomian(int size, int prompt) {
		
		wspol.reserve(size);
		wspol.assign(size, prompt);
	}
	
	//----------------------------------
	
	wielomian::wielomian(double wart) {
		wspol.push_back(wart);
	}
	
	//----------------------------------
	
	wielomian::wielomian(double *tab, int size) {
		
		for(int i=0; i < size; ++i)
			wspol.push_back(*(tab+i));
	}
	
	//----------------------------------
	
	wielomian::wielomian(const vector<double> &tab) {
		wspol = tab;
	}
	
	//----------------------------------
	
	void wielomian::wypelnij_zerami(int ile_zer) {
		
		wspol.insert(wspol.begin(), ile_zer, 0);
		
	return;	
	}
	
	//----------------------------------
	
	void wielomian::usun_zb_zera() {
		
		vector<double>::iterator loc=wspol.begin();
		
		for(int i=0, s=wspol.size(); i < s; ++i)
			if((*this)[i] == 0)
				loc++;
			else
				break;
				
		wspol.erase(wspol.begin(), loc);
		
	return;	
	}
	
	//----------------------------------
	
	double wielomian::operator()(double param) {
		double wynik(0);
		
		if(*this) {
			for(int i=0; i < wspol.size()-1; ++i)
				wynik += wspol[i] * param;
			
			wynik += wspol[wspol.size()-1];
		}
		
	return wynik;
	}
	
	//----------------------------------
	
	double &wielomian::operator[](unsigned index) {
	
	return wspol.at(index);
	}
	
	//----------------------------------
	
	wielomian::operator bool() {
		
	return wspol.size();
	}
	
	//----------------------------------
	
	wielomian wielomian::operator+=(wielomian wiel) {
		*this = *this + wiel;
		
	return *this;	
	}
	
	//----------------------------------
	
	wielomian wielomian::operator-=(wielomian wiel) {
		*this = *this - wiel;
		
	return *this;	
	}
	//----------------------------------
	
	wielomian wielomian::operator*=(wielomian wiel) {
		*this = *this * wiel;
		
	return *this;	
	}
	
	//----------------------------------
	
	wielomian wielomian::operator/=(wielomian wiel) {
		*this = *this / wiel;
		
	return *this;	
	}
	
	//----------------------------------
	
	wielomian wielomian::operator%=(wielomian wiel) {
		*this = *this % wiel;
		
	return *this;	
	}
	
	//----------------------------------
	
	int wielomian::st() {
		if(wspol.size() == 0)
			return -1;
		else
			return wspol.size()-1;
	}
	
	
	
	//-----------------------------------------------------------------------------------------------
	
	wielomian operator+(wielomian wiel1, wielomian wiel2) {
		if(!wiel1 || !wiel2)
			return 0.0;
		
		int st1(wiel1.st()), st2(wiel2.st());
		int roznica_st( abs( static_cast<int>( st1 - st2 ) ) );
		int max_st(0);
		
		if(st1 < st2) {
			wiel1.wypelnij_zerami(roznica_st);
			max_st = st2+1;
		}
		else {
			wiel2.wypelnij_zerami(roznica_st);
			max_st = st1+1;
		}
		
		wielomian suma(max_st);
		
		for(int i=0; i < max_st; ++i)
			suma[i] = wiel1[i] + wiel2[i];
		
		suma.usun_zb_zera();
		
	return suma;
	}
	
	//----------------------------------
	
	wielomian operator-(wielomian wiel1, wielomian wiel2) {
		if(!wiel1 || !wiel2)
			return 0.0;
			
		int st1(wiel1.st()), st2(wiel2.st());
		int roznica_st( abs( static_cast<int>( st1 - st2 ) ) );
		int max_st(0);
		
		if(st1 < st2) {
			wiel1.wypelnij_zerami(roznica_st);
			max_st = st2+1;
		}
		else {
			wiel2.wypelnij_zerami(roznica_st);
			max_st = st1+1;
		}
		
		wielomian suma(max_st);
		
		for(int i=0; i < max_st; ++i)
			suma[i] = wiel1[i] - wiel2[i];
		
		suma.usun_zb_zera();
		
	return suma;
	}
	
	//----------------------------------
	
	wielomian operator*(wielomian wiel1, wielomian wiel2) {
		if(!wiel1 || !wiel2)
			return 0.0;
		
		int st1(wiel1.st()), st2(wiel2.st());
		wielomian iloczyn(st1+st2+1);
			
		for(int i=0; i <= st1; ++i)
			for(int j=0; j <= st2; ++j)
				iloczyn[i+j] += wiel1[i] * wiel2[j];
		
	return iloczyn;
	}
	
	//----------------------------------
	
	wielomian operator/(wielomian wiel1, wielomian wiel2) {
		if(!wiel1 || !wiel2)
			return 0.0;
		
		else if(wiel1.st() >= wiel2.st()) {
			wielomian reszta(wiel1), iloraz, x;
					
			while( reszta.st() >= wiel2.st() ) {
				x.wspol.erase( x.wspol.begin(), x.wspol.end() );
				x.wspol.push_back( reszta[0] / wiel2[0] );
				x.wspol.insert( x.wspol.end(), reszta.st()-wiel2.st(), 0 );
				
				reszta = reszta - (x * wiel2);
				
				iloraz.wspol.push_back(x[0]);
			}
			
			return iloraz;
		}
		
		else
			return 0.0;
	}
	
	//----------------------------------
	
	wielomian operator%(wielomian wiel1, wielomian wiel2) {
		if(!wiel1 || !wiel2)
			return 0.0;
		
		else if(wiel1.st() >= wiel2.st()) {
			wielomian reszta(wiel1), x;
					
			while( reszta.st() >= wiel2.st() ) {
				
				x.wspol.erase( x.wspol.begin(), x.wspol.end() );
				x.wspol.push_back( reszta[0] / wiel2[0] );
				x.wspol.insert( x.wspol.end(), reszta.st()-wiel2.st(), 0 );
				
				reszta = reszta - (x * wiel2);
			}
			
			return reszta;
		}
		
		else
			return 0.0;
	}
	
	//----------------------------------
	
	ostream &operator<<(ostream &cout, wielomian wiel) {
		
		if(!wiel)
			return cout << "Wielomian zerowy";
		
		else {
			for(int i=0, stopien=wiel.wspol.size(); i < stopien; ++i) {
				
				double pisany = wiel[i];
				
				// wyťwietlanie wspˇ│czynnikˇw
				if(pisany == 0)
					continue;
				
				else if(i > 0 && i < stopien-1) {
					if(pisany == 1)
						cout << "+";
					else if(pisany == -1)
						cout << "-";
					else
						cout << showpos << pisany << resetiosflags(ios::showpos);
				}
				
				else if(i == 0) {
					if(i == wiel.wspol.size()-1)
						cout << pisany;
					else if(pisany == 1);
					else if(pisany == -1)
						cout << "-";
					else
						cout << pisany;
				}
				
				else
					cout << showpos << pisany << resetiosflags(ios::showpos);
				
				//wyťwietlanie wk│adnikˇw potŕg
				if(stopien-i-1 > 1)
					cout << setclr(YELLOW) << setbk(BLACK) << "x^" << stopien-i-1;
				else if(stopien-i-1 == 1)
					cout << setclr(YELLOW) << setbk(BLACK) << "x";
				
				cout << setclr(LIGHTGRAY) << setbk(BLACK) ;
			}
			
		}
		
	return cout;
	}
	
	//----------------------------------
	
	istream &operator>>(istream &in, wielomian &wiel) {
		
		// czytamy dopˇki nie napotkamy znaku '\n'
		while(in.peek() != '\n') {
			double buf;
			in >> buf;
			wiel.wspol.push_back(buf);
		}
		
		// wyrzucamy znak '\n' ze strumienia
		cin.ignore();
		// usuwamy zbŕdne zera
		wiel.usun_zb_zera();
		
	return in;
	}
	
	//----------------------------------

} // namespace dx

#endif
0

@dzidex: to miało być czyste C, czyli mniej więcej coś takiego:

struct TPolymial
{
private:
    double * a;
    int  degree;
    ReserveMem(double leadingCoeff=1.0)
    {
         int i;
         a = (double*)calloc(sizeof(double),degree+1);
         if(a==0) exit(1);
         for(i=0;i<degree;i++)
             a[i] = 0.0;
         a[degree]=leadingCoeff;
    }
public:
    TPolymial(int deg):degree(deg)
    {
        ReserveMem();
    }

    TPolymial(TPolymial & source):degree(source.degree)
    {
         a = (double*)calloc(sizeof(double),degree+1);
         if(a==0) exit(1);
         for(i=0;i<=degree;i++)
             a[i] = source.a[i];
    }


    TPolymial(int deg, double leadingCoeff):degree(deg)
    {
        ReserveMem(leadingCoeff);
    }

    TPolymial(int deg, double Coeff[]):degree(deg)
    {
        ReserveMem();
        for(int i=0;i<=degree;i++)
             a[i] = Coeff[i];
    }

    ~TPolymial()
    {
        if(a!=0) free(a);
    }

    double & operator[](int i)
    {
         if((i>=0) && (i<=degree))
             return a[i];
         // todo: error index
    }

    TPolymial & operator+=(TPolymial & b)
    {
         if(degree<b.degree)
         {
              int i,oldDegree=degree;
              double * temp = a;
              degree=b.degree;
              ReserveMem(0.0);
              for(i=0;i<=oldDegree;i++)
                  a[i]=temp[i];
              free(temp);
         }
         for(int i=0;i<=b.degree;i++)
               a[i]+=b[i];
         return *this;
    }

    TPolymial operator+(TPolymial & b)
    {
        if(degree<b.degree) // optymalizacja
            return TPolymial(b)+=*this;
            else return TPolymial(*this)+=b;

    }

    // i tak dalej
};

Poza tym domyślna wartość wiodącego współczynnika powinna być różna od zera (równa np 1.0).
Inne niedoskonałości twojego kodu to raczej powinno się definiować operator + za pomocą += a nie na odwrót, ponieważ unika się wtedy zbyt częstego stosowania konstruktorów kopiujących.

0

Marek, ale głupia sprawa ;) W C nie ma konstruktorów, metod, ani słów private,public, referencji też. Już nie mówiąc o przeładowaniu operatorów, bo tam nawet zwykłych funkcji nie można przeładowywać ;P

zasadniczo, tylko 1-szy punkt da się zrealizować w C, reszta z definicji jest nie tylko niemożliwa - w C nie istnieją nawet pojęcia, o których w tych punktach jest mowa (przeładowanie, konstruktor).

IMHO tam albo ma być "czyste C++" (znaczy, w sensie np ISO) albo autorowi coś się zamotało. Autora zresztą nie chcę komentować...

0

Racja, miałem właśnie takie przeczucie. Jednak za rzadko piszę w C by zaufać intuicji.

0
quetzalcoatl napisał(a)
Pyku napisał(a)

klasy modelującej wielomian jednej zmiennej. Ma być to zrealizowane w "czystym C", ale oczywiście nie pogardzę programem, pomocą w języku C++

w C nie ma klas.
tylko w C++ sa.
zdecyduj sie..

:)))

a potem autor dopisal ze sam nie wie.. pewnie mialo byc to C++, tylko nauczyciel tez nie wiedzial..

0

marek:
Spoko, łatwo zamotać się, jak ktoś chce "klasę w C, która przeładowuje operatory"... ;) Zresztą, IMO program zamieniłeś na "ducha C" na tyle, na ile tylko się da, wywalając STLa, a dając w zamian żonglowanie pointerami i calloc. Może wykładowcy zależy na właśnie takim surowym grzebaniu w pamięci, wtedy twoja poprawka baaardzo się przyda.

quetzalcoatl, bawiąc się psychoanalityka... może właśnie nauczycielowi chodziło o olanie STL? Zresztą, nie mój problem, a szczerze mówiąc, to trochę mnie nawet drażni, że problem rozwiązany ;]

DzieX, podziwiam wielkoduszność, ja sam wredota jestem, nie potrafiłbym.

1 użytkowników online, w tym zalogowanych: 0, gości: 1