Pomoc ze zbudowaniem klasy – kilka pytań

0

Witam,
znowu poproszę o pomoc. Tym razem dłuższy projekt i pewnie będę miał setki pytań. Dość sporo czytałem o programowaniu obiektowym ale musicie wiedzieć, że jestem początkujący. Próbowałem wcześniej zrobić proste klasy ale już gdy mam się podpasować pod narzucone zadanie to nie wiem co i jak zrobić.

Treść zadania:
Napisz klasę "poly" tak, aby mogła ona być użyta w przykładzie zaprezentowanym w pliku testpoly.cpp. Wykorzystaj w tym celu jeden z kontenerów bibliteki STL.
Napisz klasę którą będzie można użyć dla danego kodu. Użyj konteneru bibilioteki STL (Tutaj z tego co wiem chodzi o vector)

Kod pod który mam zrobić klasę:

#include <iostream>
using namespace std;
#include "poly.h"


int main(void)
{
  poly P1;				//Declare object representing polynomial P1
  P1[3] = 2; P1[1] = 3.6; P1[0] = 7;	//Specify coefficients of P1 = 2x^3 + 3.6x + 7
  
  poly P2 = 5;				//Declare object representing polynomial P2 = 5
  P2[1] = 3; P2[2] = 6; P2[4] = 1;	//Specify additional coefficients of P2 = x^4 + 6x^2 + 3x + 5
  
  cout << "Polynomial P1: " << P1 << endl;	//Print P1 	
  cout << "Polynomial P2: " << P2 << endl;	//Print P2
  
  poly P3 = P1 + P2;						//Add P1 and P2 	
  cout << "Sum of polynomials P1 and P2: " << P3 << endl;	//Print sum of P1 and P2
  
  P3 = P1 * P2;							//Multiply P1 by P2 	
  cout << "Product of polynomials P1 and P2: " << P3 << endl;	//Print product of P1 and P2

  P3 = 2 * P1;							//Multiply P1 by 2 	
  cout << "Polynomial P1 multiplied by 2: " << P3 << endl;	//Print product of P1 and 2
  
  double val = P1(3.14);						//Calculate the value of P1 at point 3.14
  cout << "Value of polynomial P1 at point 3.14: " << val << endl;	//Print the value of P1 at point 3.14
};

Z tego co do tej pory się nauczyłem to muszę w klasie mieć takie rzeczy jak:

  • jakiś operator do tego:
P1[ 3 ] = 2;
i innych P1 / P2 / P3

Zaprzyjaźniony operator ostream dla tego:

cout << "Polynomial P1: " << P1 << endl;

Operatory dodawania i mnożenia dla tego:

poly P3 = P1 + P2; //Add P1 and P2 
//..
P3 = P1 * P2; //Multiply P1 by P2 
//..
P3 = 2 * P1; //Multiply P1 by 2 

Coś do tego:

double val = P1( 3.14 );

na razie zrobiłem szablon - podstawę do zrobienia czegokolwiek. Będę potrzebował pomocy z całą resztą ale oczywiście nie oczekuję gotowego kodu do zadania, a chętnie przez kilka dni posiedzę nad takim projektem :D

Mój kod:

#include <iostream>
#include <vector>
using namespace std;

class Wielomian
{
private:
vector <double> dane;
 
public:
	
    Wielomian();   //Nie wiem co w konstruktorze           
 
    friend Wielomian operator +(const Wielomian& A, const Wielomian& B); // +
    friend Wielomian operator *(const Wielomian& A, const Wielomian& B); // *
};
 
// suma
 Wielomian operator+(const Wielomian& A, const Wielomian& B) 
{

}
// iloczyn
Wielomian operator*(const Wielomian& A, const Wielomian& B) 
{

}


//ostream do cout'a
ostream& operator<<(ostream& o, const Wielomian& w)
{
//tu nie wiem jeszcze co będzie
}
 
int main()
{
cout<< "Hello World" <<endl;
 return 0;
}

vector już też wrzuciłem mimo, że jeszcze z niego nie umiem korzystać ale myślę, że dam radę.

Prosiłbym o informację co jeszcze i jak wrzucić do szablonu.
Wiem, że jest potrzebne jeszcze
Coś do tego:

double val = P1( 3.14 );

i jakiś operator do tego:

P1[ 3 ] = 2;
i innych P1 / P2 / P3 

ale nie bardzo wiedziałem jak to zapisać.

Za każdą pomoc daję lajki i jestem mega wdzięczny. Proszę nie hejtować, bo potrzebuję pomocy w nauce i co najwyżej proszę krytykować mój kod :D

2

Bracie @wiezaawieza generalnie dobrze kombinujesz, zalecałbym jednak siąść nad jakąś książką do C++ i poczytać, co daje definiowanie operatorów jako metodę klasy a co jako oddzielną funkcję.
Co do ciał funkcji - to ja już za stary jestem, i dodawania/mnożenia/dzielenia wielomianów nie pamiętam. Ale w gógle znajdziesz bez problemu odpowiednie metody numeryczne.
Co do tego

double val = P1( 3.14 );

to będziesz chciał operator(), a wynikiem o ile dobrze zrozumiałem ma być podstawienie pod x w wielomianie tego 3.14, obliczenie wartości wielomianu i zwrócenie.Czyli tak:

double operator()(double valueForX)
{
      return //tu wartość twojego wielomian po podstawieniu valueForX
}
0

Dziękuję @MasterBLB za kolejną pomoc :D

Co do książek to niestety żadnej nie mam ale wszystko staram się znaleźć w internecie i póki co się udaje czegoś nauczyć po zrobieniu każdego programu.

Wyczytałem, że najlepiej definiować operatory jako metodę praktycznie zawsze. Ale jeśli nasz operator dotyczy dwóch klas to już w funkcji żeby uniknąć pewnych problemów.

U nas będzie jedna klasa więc zdefiniowałem operator jako metodę poza klasą (w klasie tylko jest jej definicja, a funkcja poza klasą). Tak więc nie wiem czy powinienem coś zmienić w tym zapisie.

Twój kod dopisałem do programu ale musiałem to dodać w klasie, bo inaczej wyrzucało błąd "operator () must be a nonstatic member function".

Znalazłem metody do + i * wielomianów i je dodałem. Ale jest to więcej kodu niż same metody więc będzie trzeba posprzątać itd.

Obecny kod (kompiluje się po poprawkach więc nie jest najgorzej):

#include <iostream>
#include <vector>
using namespace std;

class Wielomian
{
private:
	vector <double> dane;
    int n;                          // stopien wielomianu
    double *wsp;                    // wspolczynniki wielomianu
public:
	
    Wielomian(int _n);              // konstrktor
    Wielomian(const Wielomian& w);  // konstruktor kopiujacy

    friend Wielomian operator +(const Wielomian& A, const Wielomian& B); // +
    friend Wielomian operator *(const Wielomian& A, const Wielomian& B); // *
    
	double operator()(double valueForX)  //double val = P1( 3.14 );
	{
    	  return 1; //tu wartość twojego wielomian po podstawieniu valueForX
	}
};
 
 Wielomian::Wielomian(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
 Wielomian::Wielomian(const Wielomian& w) // copy
 {
    n= w.n;
    wsp= new double[n];
 for (int i=n; i>=0; i--)
    {
        wsp[i]=w.wsp[i];
    }
}
 

// suma
 Wielomian operator+(const Wielomian& A, const Wielomian& B) 
{
    int n;
 if (A.n>=B.n)
    {
        n=A.n;
    }
    else
    {
        n=B.n;
    }
 Wielomian w(n);
    w.wsp = new double[w.n];
  for (int i=w.n; i>=0; i--)
{
        w.wsp[i]=A.wsp[i]+B.wsp[i];
}
 return w;
}
// iloczyn
Wielomian operator*(const Wielomian& A, const Wielomian& B) 
{
    Wielomian w(A.n+B.n); 
for (int i=0; i<=w.n; i++)w.wsp[i]=0;   
    for (int i=0; i<=A.n; i++)
{
    for (int j=0; j<=B.n; j++)
{
    w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
}}
    return w;
}


//ostream do cout'a
ostream& operator<<(ostream& o, const Wielomian& w)
{
//tu nie wiem jeszcze co będzie
}
 
int main()
{
cout<< "Hello World" <<endl;
 
    return 0;
}

Kod wziąłem z programu który obliczał wszystko dla losowego wielomianu. Trzeba będzie zupełnie zmienić konstruktor (nie wiem czy konstruktor kopiujący i destruktor nam będzie potrzebny ale czytałem, że jak już się vectora używa to potrzeba tylko konstruktora).

Co do konstruktora to potrzebuję pomocy, bo jestem na poziomie gdzie nie widzę w przód co musi w nim być patrząc na ten kod z zadania. Wydaje mi się, że sam int wystarczy do współczynnika wielomianu, bo P1 itd to w zadaniu były współczynniki wielomianu i na nich są wszystkie operacje.

Co do wymagań to nie wiem o co pytasz, bo polecenie jest dość krótkie w zadaniu i nic szczególnego nie ma poza "stwórz klasę do podanego kodu i użyj kontenera z stl". Wymaganie jest tylko żeby klasa pasowała pod ten kod podany w zadaniu

1

Najsampierw to trzeba się zorientować czym będzie wielomian w tym programie, chodzi mi tutaj o zbiorcze wymagania do niego. Np ma mieć tylko jedną zmienną x, czy może być ich więcej? x^2 + y - 5z^3 to też wielomian.

W każdym razie, przyjmując na razie iż występować będzie zmienna x dowolny wielomian składa się z szeregu takich jednomianów:

(znak +/-)Ax^y

gdzie A to mnożnik, a y potęga. Zatem przekładając to na kod C++ można by stworzyć strukturę jednomianu

struct Jednomian
{
    double mnoznik;
    double potega;
};

Co z samodzielnymi liczbami? Dla nich potęga będzie = 0, a mnożnik wraz ze znakiem wartością - np żeby otrzymać -7 to dane w strukturze byłby mnoznik = -7 potega = 0
I teraz myk co do twojej klasy - zwierałaby ów tajemny pojemik STL w postaci:

std::vector<Jednomian> składoweWielomianu;

Niestety, póki nie wyjaśnisz zagadnienia wspomnianego na początku tego postu to dalej się nie posuniemy.

0

Wystarczy, że zrobimy to tylko dla wielomianów zawierających x (np. x^2+x+5)
Tak myślałem właśnie, że struktura się przyda.

A zatem dodałem tę strukturę i vector. Trochę błędów wyrzucało ale udało się wszystko poprawić itd.
"ł" wyrzucało błąd stray \263
kolejność w klasie wyrzucała błędy, że Jednomian nie jest zadeklarowany. Musiałem Private razem z vectorem dać poniżej struktury. Wyciągam wiedzę z każdego błędu co mnie motywuje :D

Zastanawiam się co będzie miał robić konstruktor. Przyjmie stopień wielomianu i dopisze go do tablicy żeby później móc operować na tych stopniach? Czy jakoś bez tablic... :(
Patrzę na kod z zadania i nie wiem jak to wszystko ma wyglądać :/ Mam nadzieję, że mi ta umiejętność wejdzie po zrobieniu którejś klasy...

Obecny kod:

 #include <iostream>
#include <vector>
using namespace std;

class Wielomian
{
private:
    int n;                          // stopien wielomianu
    double *wsp;                    // wspolczynniki wielomianu
public:
	
    Wielomian(int _n);              // konstrktor
    Wielomian(const Wielomian& w);  // konstruktor kopiujacy

    friend Wielomian operator +(const Wielomian& A, const Wielomian& B); // +
    friend Wielomian operator *(const Wielomian& A, const Wielomian& B); // *
    
	double operator()(double valueForX)  //double val = P1( 3.14 );
	{
    	  return 1; //tu wartość twojego wielomian po podstawieniu valueForX
	}
	
	struct Jednomian
	{
    double mnoznik;
    double potega;
	};
	private:
	std::vector<Jednomian> skladoweWielomianu;
};
 
 Wielomian::Wielomian(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
 Wielomian::Wielomian(const Wielomian& w) // copy
 {
    n= w.n;
    wsp= new double[n];
 for (int i=n; i>=0; i--)
    {
        wsp[i]=w.wsp[i];
    }
}
 

// suma
 Wielomian operator+(const Wielomian& A, const Wielomian& B) 
{
    int n;
 if (A.n>=B.n)
    {
        n=A.n;
    }
    else
    {
        n=B.n;
    }
 Wielomian w(n);
    w.wsp = new double[w.n];
  for (int i=w.n; i>=0; i--)
{
        w.wsp[i]=A.wsp[i]+B.wsp[i];
}
 return w;
}
// iloczyn
Wielomian operator*(const Wielomian& A, const Wielomian& B) 
{
    Wielomian w(A.n+B.n); 
for (int i=0; i<=w.n; i++)w.wsp[i]=0;   
    for (int i=0; i<=A.n; i++)
{
    for (int j=0; j<=B.n; j++)
{
    w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
}}
    return w;
}


//ostream do cout'a
ostream& operator<<(ostream& o, const Wielomian& w)
{
//tu nie wiem jeszcze co będzie
}
 
int main()
{
cout<< "Hello World" <<endl;
 
    return 0;
}
2

W twoim wypadku konstruktor chyba nie będzie musiał nic robić ^^ Na tą chwilę trzeba by dać możliwość zbudowania dowolnych wielomianów. W tym celu klasa Wielomian będzie potrzebować:

class Wielomian
{
public:
  void dodajSkladnikWielomianu(double mnoznik , double potega)
  {
       Jednomian jednomian;
       jednomian.mnoznik = mnoznik;
       jednomian.potega = potega;
       
       skladoweWielomianu.push_back(jednomian);
  }
}

ok, to teraz jak by wyglądało zbudowanie w kodzie tego przykładowego wielomianu x^2+x+5

Wielomian P1;
P1.dodajSkladnikWielomianu(1, 2);//+1x^2
P1.dodajSkladnikWielomianu(1, 1);//+1x^1
P1.dodajSkladnikWielomianu(5, 0);//+5x^0

hmmm ćwiczenie dla ciebie - a jak by to wyglądało dla wielomianu 1/3x^4 - x^0.99 - 4x - 6 ? :]

0
MasterBLB napisał(a):

hmmm ćwiczenie dla ciebie - a jak by to wyglądało dla wielomianu 1/3x^4 - x^0.99 - 4x - 6 ? :]

Różni ludzie by się spierali że ta ostatnia nie jest wielomianem, bo chociażby jaką wartość osiąga w -1? x^0.99 nie jest wtedy określony.

0

Samego voida do klasy dodałem bez problemu ale gdy próbowałem dodać tę drugą część kodu budującą wielomian to wyrzuciło sporo błędów. Głównie

	[Error] no matching function for call to 'Wielomian::Wielomian()'

Próbowałem zrobić to wrzucając kod do maina, potem po zobaczeniu błędu zrobiłem funkcję w klasie mając nadzieję, że to coś pomoże ale nadal jest ten błąd. I pewnie samo "Wielomian P1;" powinienem odłączyć od reszty budowy wielomianu tylko szczerze nie wiem gdzie. Ze strukturami to pamiętam, że po kodzie struktury dopisywało się takie rzeczy ale tutaj ma to być dołączone do klasy chyba więc nie ogarniam :(

Co do twojego pytania to chętnie bym to sprawdził w programie ale jak myślę byłoby to:
1/3x^4 - x^0.99 - 4x - 6 ?

P1.dodajSkladnikWielomianu(1/3, 4)   //  1/3x^4
P1.dodajSkladnikWielomianu(-1, 0.99)  //  -x^0.99
P1.dodajSkladnikWielomianu(-4, 1) //  -4x
P1.dodajSkladnikWielomianu(-6, 0); //  -6

Jedynie nie wiem czy program zaakceptuje 1/3 ale myślę że tak.

 #include <iostream>
#include <vector>
using namespace std;

class Wielomian
{
private:
    int n;                          // stopien wielomianu
    double *wsp;                    // wspolczynniki wielomianu
public:
	
    Wielomian(int _n);              // konstrktor
    Wielomian(const Wielomian& w);  // konstruktor kopiujacy

    friend Wielomian operator +(const Wielomian& A, const Wielomian& B); // +
    friend Wielomian operator *(const Wielomian& A, const Wielomian& B); // *
    
	double operator()(double valueForX)  //double val = P1( 3.14 );
	{
    	  return 1; //tu wartość twojego wielomian po podstawieniu valueForX
	}
	
	struct Jednomian
	{
    double mnoznik;
    double potega;
	};
	private:
	std::vector<Jednomian> skladoweWielomianu;
	public:
  void dodajSkladnikWielomianu(double mnoznik , double potega)
  {
       Jednomian jednomian;
       jednomian.mnoznik = mnoznik;
       jednomian.potega = potega;
 
       skladoweWielomianu.push_back(jednomian);
  }
  void test()
{
Wielomian P1;
P1.dodajSkladnikWielomianu(1, 2);//+1x^2
P1.dodajSkladnikWielomianu(1, 1);//+1x^1
P1.dodajSkladnikWielomianu(5, 0);//+5x^0
}
};
 
 Wielomian::Wielomian(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
 Wielomian::Wielomian(const Wielomian& w) // copy
 {
    n= w.n;
    wsp= new double[n];
 for (int i=n; i>=0; i--)
    {
        wsp[i]=w.wsp[i];
    }
}
 

// suma
 Wielomian operator+(const Wielomian& A, const Wielomian& B) 
{
    int n;
 if (A.n>=B.n)
    {
        n=A.n;
    }
    else
    {
        n=B.n;
    }
 Wielomian w(n);
    w.wsp = new double[w.n];
  for (int i=w.n; i>=0; i--)
{
        w.wsp[i]=A.wsp[i]+B.wsp[i];
}
 return w;
}
// iloczyn
Wielomian operator*(const Wielomian& A, const Wielomian& B) 
{
    Wielomian w(A.n+B.n); 
for (int i=0; i<=w.n; i++)w.wsp[i]=0;   
    for (int i=0; i<=A.n; i++)
{
    for (int j=0; j<=B.n; j++)
{
    w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
}}
    return w;
}


//ostream do cout'a
ostream& operator<<(ostream& o, const Wielomian& w)
{
//tu nie wiem jeszcze co będzie
}
 
int main()
{
cout<< "Hello World" <<endl;


    return 0;
}

zrobiłem void test() i pewnie funkcja powinna przyjmować argumenty jakieś ale chciałem po prostu żeby w mainie się to odpaliło i mam następujące błędy:

	In member function 'void Wielomian::test()':
41	11		[Error] no matching function for call to 'Wielomian::Wielomian()'
41	11		[Note] candidates are:
13	5		[Note] Wielomian::Wielomian(const Wielomian&)
13	5		[Note] candidate expects 1 argument, 0 provided
12	5		[Note] Wielomian::Wielomian(int)
12	5		[Note] candidate expects 1 argument, 0 provided

1

Poprawiłem do postaci kompilowalnej, oraz dałem tworzenie wielomianu z jednomianów w main()

#include <iostream>
#include <vector>
using namespace std;

class Wielomian
{
private:
    struct Jednomian
    {
        double mnoznik;
        double potega;
    };

   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
   std::vector<Jednomian> skladoweWielomianu;

public:
    Wielomian() = default;
    Wielomian(int _n);              // konstrktor
    Wielomian(const Wielomian& w);  // konstruktor kopiujacy

    void dodajSkladnikWielomianu(double mnoznik , double potega)
    {
          Jednomian jednomian;
          jednomian.mnoznik = mnoznik;
          jednomian.potega = potega;

          skladoweWielomianu.push_back(jednomian);
    }

//Przeciążone operatory
    friend Wielomian operator +(const Wielomian& A, const Wielomian& B); // +
    friend Wielomian operator *(const Wielomian& A, const Wielomian& B); // *

    double operator()(double valueForX)  //double val = P1( 3.14 );
    {
          return 1; //tu wartość twojego wielomian po podstawieniu valueForX
    }    
};

Wielomian::Wielomian(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Wielomian::Wielomian(const Wielomian &w) // copy
{
   n= w.n;
   wsp= new double[n];
for (int i=n; i>=0; i--)
   {
       wsp[i]=w.wsp[i];
   }
}

// suma
Wielomian operator+(const Wielomian& A, const Wielomian& B)
{
   int n;
if (A.n>=B.n)
   {
       n=A.n;
   }
   else
   {
       n=B.n;
   }
Wielomian w(n);
   w.wsp = new double[w.n];
 for (int i=w.n; i>=0; i--)
{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
}
return w;
}
// iloczyn
Wielomian operator*(const Wielomian& A, const Wielomian& B)
{
   Wielomian w(A.n+B.n);
for (int i=0; i<=w.n; i++)w.wsp[i]=0;
   for (int i=0; i<=A.n; i++)
{
   for (int j=0; j<=B.n; j++)
{
   w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
}}
   return w;
}

//ostream do cout'a
ostream& operator<<(ostream& o, const Wielomian& w)
{
//tu nie wiem jeszcze co będzie
}

int main()
{
    cout<< "Hello World" <<endl;

    Wielomian P1;
    P1.dodajSkladnikWielomianu(1, 2);//+1x^2
    P1.dodajSkladnikWielomianu(1, 1);//+1x^1
    P1.dodajSkladnikWielomianu(5, 0);//+5x^0

    return 0;
}

Ale wiedz Bracie wiezaawieza, iż taki burdel dalej być nie może.Deklarację klasy Wielomian należy dać do pliku wielomian.h, definicje metod do wielomian.cpp, a do maina #include "wielomian.h" - tym się zajmij teraz.

0

wielomian.h:

#include <iostream>
#include <vector>
using namespace std;
 
class Wielomian
{
private:
    struct Jednomian
    {
        double mnoznik;
        double potega;
    };
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
   std::vector<Jednomian> skladoweWielomianu;
 
public:
    Wielomian() = default;
    Wielomian(int _n);              // konstrktor
    Wielomian(const Wielomian& w);  // konstruktor kopiujacy
 
    void dodajSkladnikWielomianu(double mnoznik , double potega)
    {
          Jednomian jednomian;
          jednomian.mnoznik = mnoznik;
          jednomian.potega = potega;
 
          skladoweWielomianu.push_back(jednomian);
    }
 
//Przeciążone operatory
    friend Wielomian operator +(const Wielomian& A, const Wielomian& B); // +
    friend Wielomian operator *(const Wielomian& A, const Wielomian& B); // *
 
    double operator()(double valueForX)  //double val = P1( 3.14 );
    {
          return 1; //tu wartość twojego wielomian po podstawieniu valueForX
    }    
};

wielomian.cpp:

#include "wielomian.h"
Wielomian::Wielomian(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Wielomian::Wielomian(const Wielomian &w) // copy
{
   n= w.n;
   wsp= new double[n];
for (int i=n; i>=0; i--)
   {
       wsp[i]=w.wsp[i];
   }
}
 
// suma
Wielomian operator+(const Wielomian& A, const Wielomian& B)
{
   int n;
if (A.n>=B.n)
   {
       n=A.n;
   }
   else
   {
       n=B.n;
   }
Wielomian w(n);
   w.wsp = new double[w.n];
 for (int i=w.n; i>=0; i--)
{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
}
return w;
}
// iloczyn
Wielomian operator*(const Wielomian& A, const Wielomian& B)
{
   Wielomian w(A.n+B.n);
for (int i=0; i<=w.n; i++)w.wsp[i]=0;
   for (int i=0; i<=A.n; i++)
{
   for (int j=0; j<=B.n; j++)
{
   w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
}}
   return w;
}
 
//ostream do cout'a
ostream& operator<<(ostream& o, const Wielomian& w)
{
//tu nie wiem jeszcze co będzie
}
 
int main()
{
    cout<< "Hello World" <<endl;
 
    Wielomian P1;
    P1.dodajSkladnikWielomianu(1, 2);//+1x^2
    P1.dodajSkladnikWielomianu(1, 1);//+1x^1
    P1.dodajSkladnikWielomianu(5, 0);//+5x^0

    return 0;
}

Zrobiłem i wszystko się kompiluje więc raczej dobrze. Jedynie nie wiem do końca czy chciałeś żebym utworzył jeszcze osobny plik np. wielomianmain.cpp z samym kodem:

#include <iostream>

using namespace std;
#include "wielomian.h" 

int main()
{
    cout<< "Hello World" <<endl;
 
    Wielomian P1;
    P1.dodajSkladnikWielomianu(1, 2);//+1x^2
    P1.dodajSkladnikWielomianu(1, 1);//+1x^1
    P1.dodajSkladnikWielomianu(5, 0);//+5x^0

    return 0;
}

czy chodziło o tamten kod z zadania i miałem utworzyć coś takiego:

#include <iostream>
using namespace std;
#include "wielomian.h" 
 
int main(void)
{
  poly P1;              //Declare object representing polynomial P1
  P1[3] = 2; P1[1] = 3.6; P1[0] = 7;    //Specify coefficients of P1 = 2x^3 + 3.6x + 7
 
  poly P2 = 5;              //Declare object representing polynomial P2 = 5
  P2[1] = 3; P2[2] = 6; P2[4] = 1;  //Specify additional coefficients of P2 = x^4 + 6x^2 + 3x + 5
 
  cout << "Polynomial P1: " << P1 << endl;  //Print P1  
  cout << "Polynomial P2: " << P2 << endl;  //Print P2
 
  poly P3 = P1 + P2;                        //Add P1 and P2     
  cout << "Sum of polynomials P1 and P2: " << P3 << endl;   //Print sum of P1 and P2
 
  P3 = P1 * P2;                         //Multiply P1 by P2     
  cout << "Product of polynomials P1 and P2: " << P3 << endl;   //Print product of P1 and P2
 
  P3 = 2 * P1;                          //Multiply P1 by 2  
  cout << "Polynomial P1 multiplied by 2: " << P3 << endl;  //Print product of P1 and 2
 
  double val = P1(3.14);                        //Calculate the value of P1 at point 3.14
  cout << "Value of polynomial P1 at point 3.14: " << val << endl;  //Print the value of P1 at point 3.14
};

Zrobiłem każdą wersję, bo to chwila. Masz rację, że to o wiele lepiej wygląda i łatwiej się odnaleźć. Będę tak robił z innymi klasami :D

Ps: Nie znalazłem na forum opcji spoilerowania, a przydałoby się, bo sporo tego kodu wrzucam. Jakby ktoś się znał to prosiłbym o zostawienie kodu w komentarzu albo informację gdzie znaleźć spoiler.

1

To jest forum programistów, my chcemy oglądać kod :P Co do main, to docelowo będzie ten z zadania, ten który ja podałem służył jedynie do testu klasy i metody dodajJednomian.
Ok, to sprawa kolejna jaka cię czeka - przyswojenie sobie formatowania kodu:

  • pogógluj co to jest camelCase
  • wskazane jest angielskie nazewnictwo
  • każdy blok kodu zawarty w nawiasach {} powinien być wcięty tabem - wyjątek to niekiedy długie bloki namespace
  • definicje funkcji/klas/struktur od początku lewej strony, bez wcięcia (chyba że są w niedużym namespace)
  • nawiasy { } zawsze w nowej linii - nie daj się zwieść na manowce javowcom.

Taka jeszcze wskazówka do używania tego forum i zamieszczania kodu - jak używasz </> aby dać oznaczenie iż dany blok tekstu to kod wybieraj także język w jakim jest napisany.

Oook...wracając do wielomianu z przykładu 1/3x^4 - x^0.99 - 4x - 6 zastanów się, co by było jakby jako x podstawić -2? :] (podpowiedź - nasza strukturka ma jeszcze pewien brak, znajdź go)
Jak już to rozkiminisz to można będzie się wziąć za budowanie wielomianów przy pomocy

P1[3] = 2; P1[1] = 3.6; P1[0] = 7;
0

@MasterBLB: dziękuję :)

Poczytałem trochę o camelCase i postaram się dostosować do takiego zapisu. W moich kodach za wiele nie było do zmiany ale coś tam zmieniłem :P Mała zmiana ale kod wygląda ciekawiej :D

Zmieniłem nazwy na angielskie
Co do wcięć itd. to myślę, że dobrze Cię zrozumiałem i zrobiłem tak jak być powinno ale nie jestem pewien.
Całą resztę też zrobiłem. Wygląda to lepiej :D

Co do </> to klikam na ikonę i się wstawiają - ''' kod ''' . Nie widziałem nigdzie wyboru języka :(

Co do podstawiania -2:
Chodzi o znak? Dodać sprawdzanie czy znak liczby jest dodatni czy ujemny, bo inaczej źle obliczy? Tylko nasza struktura działa na potędze i mnożniku, a samym x się nie zajmujemy. Może jeszcze jakaś podpowiedź? Bo po prostu podstawiając to -2 widzę tylko możliwość problemu z tym że znak jest ujemny.

Co do kodu to dziwna sprawa, bo na windowsie w dev-C++ wyrzucało mi błędy 'Poly' does not name a Type. Tak jakby kompilator nie widział #include całego ;/ Przerzuciłem pliki na Linuxa/Ubuntu i tutaj wyrzuciło błąd

Poly.cpp in function std::ostream& operator<<(std::ostream&, const Poly&)   No return statement in function returning non-void

Jak wrzuciłem return 0; to wyskoczył kolejny błąd

Invalid initialization of non-const reference of type 'std::ostream& {aka std::basic_ostreeam<char>&}' from an rvalue of type 'int' return 0;

Więc po prostu wziąłem całego ostream'a w komentarz żeby sprawdzić czy cala reszta się kompiluje i wszystko gra. Więc po prostu ostream póki go nie zrobimy to będzie w komentarzu.

Tutaj kody:

Poly.cpp

#include "Poly.h"

Poly::Poly(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Poly::Poly(const Poly &w) // copy
{
	n= w.n;
   	wsp= new double[n];
	for (int i=n; i>=0; i--)
   		{
       		wsp[i]=w.wsp[i];
   		}
}
 
// suma
Poly operator+(const Poly& A, const Poly& B)
{
	int n;
	
	if (A.n>=B.n)
	{
    	n=A.n;
	}
	
   else
	{
    	n=B.n;
	}
	
	Poly w(n);
	w.wsp = new double[w.n];
	for (int i=w.n; i>=0; i--)
	{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
	}
	return w;
}
// iloczyn
Poly operator*(const Poly& A, const Poly& B)
{
	Poly w(A.n+B.n);
	for (int i=0; i<=w.n; i++)w.wsp[i]=0;
	for (int i=0; i<=A.n; i++)
	{
   		for (int j=0; j<=B.n; j++)
		{
			w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
		}
	}
   return w;
}

 
//ostream do cout'a
//ostream& operator<<(ostream& o, const Poly& w)
//{
//tu nie wiem jeszcze co będzie

//}
 
int main()
{
    cout<< "Hello World" <<endl;
 
    Poly P1;
    P1.addPolyComponent(1, 2);//+1x^2
    P1.addPolyComponent(1, 1);//+1x^1
    P1.addPolyComponent(5, 0);//+5x^0

    return 0;
}

Poly.h

#include <iostream>
#include <vector>
using namespace std;
 
class Poly
{
private:
struct Mono //jednomian
{
    double multiplier; //mnożnik
    double pwr; //potęga
};
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
   std::vector<Mono> polyComponents;
 
public:
    Poly() = default;
    Poly(int _n);              // konstrktor
    Poly(const Poly& w);  // konstruktor kopiujacy
 
void addPolyComponent(double multiplier , double pwr)
{
    Mono mono;
    mono.multiplier = multiplier;
    mono.pwr = pwr;
 
    polyComponents.push_back(mono);
}
 
	//Przeciążone operatory
    friend Poly operator +(const Poly& A, const Poly& B); // +
    friend Poly operator *(const Poly& A, const Poly& B); // *
 
double operator()(double valueForX)  //double val = P1( 3.14 );
{
    return 1; //tu wartość twojego wielomian po podstawieniu valueForX
}    
};

Przepraszam, że byłem nieaktywny przez weekend ale sporo się działo. Już wróciłem :D

1

Co do podstawiania -2:
Chodzi o znak? Dodać sprawdzanie czy znak liczby jest dodatni czy ujemny, bo inaczej źle obliczy? Tylko nasza struktura działa na potędze i mnożniku, a samym x się nie zajmujemy. Może jeszcze jakaś podpowiedź? Bo po prostu podstawiając to -2 widzę tylko możliwość problemu z tym że znak jest ujemny.

Przypuszczam, że w naszej strukturze będziemy potrzebowali 3 pola - łącznika z poprzednikiem,bo wielomiany z odejmowaniem kolejnych składników przy naszym obecnym zapisie mogą być źle liczone.

struct Mono //jednomian
{
    char connector;//wartość dodatnia to +, ujemna to -, zero to brak łącznika z poprzednikiem
    double multiplier; //mnożnik
    double power; //nie ma co sobie żałować na nazwie ^^
};

Dziś idę już spać, jutro zerknę coś więcej. A Ty weź napisz prościutką metodę obliczającą wartość wielomianu dla wprowadzonego x (a te przeciążone operatory na razie wykomentuj) - jak to się uda to się zrobi przeciążanie [ ]

0

Oki :)

Coś takiego może być?

double Wartosc(double multiplier, double power, double x) 
{ 
		double wynik = 0;
		int i=0;
        for (i=0; i<power; i++)
        wynik += (multiplier * x);
  
    return wynik; 
} 

Miłej nocy, też już uciekam :)

1

Nope ;] A właściwie, policzyłeś jednomian zamiast wielomianu, co możesz wykorzystać jeśli jesteś cwany :]
Chodzi o funkcję, która sobie pobiera kolejne składniki wielomianu z tego wektora polyComponents ^^
Prototyp funkcji do implementacji:

double calculatePoly(double x);
0

Z tego co ruzumiem to będzie to wyglądać jakoś tak tylko, że muszę się nauczyć jak odczytywać te wartości dla poszczególnych elementów ( coś typu. mono.power[1] - żeby zwróciło power z 2 elementu). Wiem, że to podstawa podstaw ale mam tu braki i powinienem je uzupełnić. Jakbyś miał chwilę podać jakiś przykład w celu nauki albo odesłać mnie do google z jakimś słowem kluczowym.
Kod wygląda tak. Myślę, że zamysł jest dobry, bo pobieramy te wartości składników wielomianu z polyComponents. Ale pewien nie jestem, bo to dla mnie dosyć nowość. (Mało pracowałem na strukturach/wektorach)

double calculatePoly(double x)
{
	int k=0;
	double all=0;
	for( k = 0; k < polyComponents.size(); k++ )
	{
		double result = 0;
		int i=0;
        for (i=0; i<polyComponents[k].power; i++)
        result += (polyComponents[k].multiplier * x);
  		all+= result;
		
	}
	return all;
}
1

cpp reference Twoim przyjacielem^^
Także obczaj sobie taki zapis pętli - for ( coś : pojemnik) ;)

0

Mam problem ze zrozumieniem i kompilacją.

Z tego co widzę to operator[] to jest u nas polyComponents[]. (sugeruję się tym, że na cpp referencje jest zrobione numbers[] )

Gdy chciałem odczytać co tam mam zapisane żeby wiedzieć w jaki sposób zapisują się rzeczy z funkcji addPolyComponents() to wyrzucało mi błędy. że polyComponents jest niezadeklarowane...

Main który jest w pliku Poly.cpp na samym dole:

int main()
{
    cout<< "Hello World" <<endl;
 
    Poly P1;
    P1.addPolyComponent(1, 2);//+1x^2
    P1.addPolyComponent(1, 1);//+1x^1
    P1.addPolyComponent(5, 0);//+5x^0
 for( int i=0; i< polyComponents.size() ; i++)
  cout<< polyComponents[i] << endl;
    return 0;
}

Chcę zobaczyć co jest w polyComponents, bo funkcja addPolyComponent() daje do polyComponents power i multiplier i nie wiem jak dokładnie to wygląda jak się dorzuca dwie wartości, a nie jedną.
Dość sporo dzisiaj o tym myślałem i w sumie zmarnowany dzień, bo powinienem był od razu pytać mądrzejsze osoby od siebie.

co do zapisu for ( coś : pojemnik) to zwykle spotykałem się, że było for( auto nazwaZmiennej : pojemnik).
I dziwiłem się, że w kodach na internecie nigdzie nie było żeby nazwaZmiennej była równa 0. Jutro jeszcze poszukam o tym, bo zamysł rozumiem ale auto i samego zerowania zmiennej jeszcze nie rozumiem.

1

Masz błąd polegający na tym, że dobierasz się do polyComponents które są częścią klasy Poly. Tak się tego nie da zrobić, co najwyżej:

P1.polyComponents

a i to pod warunkiem, że wektor polyComponents jest dostępny publicznie (a nie jest)

0

Przede wszystkim P1.polyComponents[i] jest strukturą, dla której nie masz przeciążonej funkcji operator<<

Nawiasem mówiąc, nie bardzo rozmiem ideę utworzenia tej struktury. To tylko dodatkowa komplikacja i całkiem niepotrzebna. Przecież możesz jako potęgi użyć po prostu indeksu vectora. A connector? Przecież liczby zmiennoprzecinkowe mają znak, więc nie widzę sensu. Jak dla mnie to tutaj wystarczy zwykły std::vector<double>. No chyba że to takie ćwiczenie, to możesz jeszcze tego double'a w strukturze rozbić na cechę i mantysę :)

0

Co do samego wyświetlania i błędów kompilacji:
Nie wiem czy chcemy to teraz załatwiać. Może @tr ma rację i najpierw trzeba zrobić to przeciążanie operatora <<
Poly.cpp:

#include "Poly.h"

Poly::Poly(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Poly::Poly(const Poly &w) // copy
{
	n= w.n;
   	wsp= new double[n];
	for (int i=n; i>=0; i--)
   		{
       		wsp[i]=w.wsp[i];
   		}
}
 
// suma
Poly operator+(const Poly& A, const Poly& B)
{
	int n;
	
	if (A.n>=B.n)
	{
    	n=A.n;
	}
	
   else
	{
    	n=B.n;
	}
	
	Poly w(n);
	w.wsp = new double[w.n];
	for (int i=w.n; i>=0; i--)
	{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
	}
	return w;
}
// iloczyn
Poly operator*(const Poly& A, const Poly& B)
{
	Poly w(A.n+B.n);
	for (int i=0; i<=w.n; i++)w.wsp[i]=0;
	for (int i=0; i<=A.n; i++)
	{
   		for (int j=0; j<=B.n; j++)
		{
			w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
		}
	}
   return w;
}

 
//ostream do cout'a
//ostream& operator<<(ostream& o, const Poly& w)
//{
//tu nie wiem jeszcze co bêdzie

//}
 
int main()
{
    cout<< "Hello World" <<endl;
 
    Poly P1;
    P1.addPolyComponent(1, 2);//+1x^2
    P1.addPolyComponent(1, 1);//+1x^1
    P1.addPolyComponent(5, 0);//+5x^0
	cout << P1.polyComponents[1] <<endl;
    return 0;
}

Poly.h :

#include <iostream>
#include <vector>
using namespace std;
 
class Poly
{
private:
struct Mono //jednomian
{
    double multiplier; //mno¿nik
    double pwr; //potêga
};
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
public:
   std::vector<Mono> polyComponents;
 
public:
    Poly() = default;
    Poly(int _n);              // konstrktor
    Poly(const Poly& w);  // konstruktor kopiujacy
 
void addPolyComponent(double multiplier , double pwr)
{
    Mono mono;
    mono.multiplier = multiplier;
    mono.pwr = pwr;
 
    polyComponents.push_back(mono);
}

 
	//Przeci¹¿one operatory
    friend Poly operator +(const Poly& A, const Poly& B); // +
    friend Poly operator *(const Poly& A, const Poly& B); // *
 
double operator()(double valueForX)  //double val = P1( 3.14 );
{
    return 1; //tu wartoæ twojego wielomian po podstawieniu valueForX
}    
};

Błędy:

Poly.cpp:77:7: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘__gnu_cxx::__alloc_traits<std::allocator<Poly::Mono> >::value_type {aka Poly::Mono}’)
  cout << P1.polyComponents[1] <<endl;

Poly.cpp:77:29:   required from here
/usr/include/c++/7/ostream:682:5: error: no type named ‘type’ in ‘struct std::enable_if<false, std::basic_ostream<char>&>’

---------------------------------------------------
---------------------------------------------------
Generalnie jak wrzuciłem tamtą funkcję calculatePoly co wcześniej zrobiłem i lekko poprawiłem to kompilator nie wyrzuca żadnego błędu. Czy ta funkcja jest bezużyteczna czy ujdzie?

Będzie sporo kodu w jednym poście ale wrzucam obydwa pliki co się kompilują - razem z funkcją calculatePoly.

Poly.h:

#include <iostream>
#include <vector>
using namespace std;
 
class Poly
{
private:
struct Mono //jednomian
{
    double multiplier; //mno¿nik
    double power; //potêga
};
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
public:
   std::vector<Mono> polyComponents;
 
public:
    Poly() = default;
    Poly(int _n);              // konstrktor
    Poly(const Poly& w);  // konstruktor kopiujacy
 
void addPolyComponent(double multiplier , double power)
{
    Mono mono;
    mono.multiplier = multiplier;
    mono.power = power;
 
    polyComponents.push_back(mono);
}
double calculatePoly(double x)
{
    unsigned int k=0;
    double all=0;
    for( k = 0; k < polyComponents.size(); k++ )
    {
        double result = 0;
        int i=0;
        for (i=0; i<polyComponents[k].power; i++)
        result += (polyComponents[k].multiplier * x);
        all+= result;
 
    }
    return all;
}

 
	//Przeci¹¿one operatory
    friend Poly operator +(const Poly& A, const Poly& B); // +
    friend Poly operator *(const Poly& A, const Poly& B); // *
 
double operator()(double valueForX)  //double val = P1( 3.14 );
{
    return 1; //tu wartoæ twojego wielomian po podstawieniu valueForX
}    
};

Poly.cpp:

#include "Poly.h"

Poly::Poly(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Poly::Poly(const Poly &w) // copy
{
	n= w.n;
   	wsp= new double[n];
	for (int i=n; i>=0; i--)
   		{
       		wsp[i]=w.wsp[i];
   		}
}
 
// suma
Poly operator+(const Poly& A, const Poly& B)
{
	int n;
	
	if (A.n>=B.n)
	{
    	n=A.n;
	}
	
   else
	{
    	n=B.n;
	}
	
	Poly w(n);
	w.wsp = new double[w.n];
	for (int i=w.n; i>=0; i--)
	{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
	}
	return w;
}
// iloczyn
Poly operator*(const Poly& A, const Poly& B)
{
	Poly w(A.n+B.n);
	for (int i=0; i<=w.n; i++)w.wsp[i]=0;
	for (int i=0; i<=A.n; i++)
	{
   		for (int j=0; j<=B.n; j++)
		{
			w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
		}
	}
   return w;
}

 
//ostream do cout'a
//ostream& operator<<(ostream& o, const Poly& w)
//{
//tu nie wiem jeszcze co bêdzie

//}
 
int main()
{
    cout<< "Hello World" <<endl;
 
    Poly P1;
    P1.addPolyComponent(1, 2);//+1x^2
    P1.addPolyComponent(1, 1);//+1x^1
    P1.addPolyComponent(5, 0);//+5x^0

    return 0;
}

A teraz idę poczytać o for ( coś : pojemnik ) to może później gdzieś tego użyję dla nauki.

2

Nauka idzie widzę w las, bo struktura Mono nie poprawiona...Widzę, iż marnie rokujesz w obecnym stanie. Nie ma bata, musisz przysiąść porządnie, i czeka cię:

  • załatwienie sobie porządnej literatury (czytaj minimum Opus Magnum C++11) - źródła w necie jak z mojej praktyki wynika są dobre raczej już dla co nieco kojarzących temat programistów, a ty jak widzę jesteś zieloniutki jak szczypiorek.
  • zrozumienie podstawowych instrukcji sterujących.
  • zrozumienie tablic, wskaźników i referencji.
  • zrozumienie idei klas.
  • zrozumienie idei klas pojemników.
  • zrozumienie na czym polega narzędzie debugger, oraz stosowaniu go.

Jak to zrobisz to poniżej zestaw kroków jakie cię czekają aby zakończyć to zadanie.

  1. umożliwienie stworzenia dowolnego wielomianu - to już częściowo masz bo po to stworzyliśmy addPolyComponent(). Jednak będąca podstawą struktura ma wspomnianą wyżej wadę.
  2. użycie funkcji calculatePoly() dla różnych x oraz wielomianów - szczególnie zwróć uwagę na wielomiany typu -x^3 - ( -0.33x^2) - 4x - 10, zacznij od jakiś prostych które możesz sobie obliczyć w pamięci. Dobra rada na przyszłość - tutaj możesz zapoznać się z ideą testów automatycznych.
  3. jak już kalkulacje będą dawać poprawny wynik będzie to oznaczało, że możesz się wziąć za reimplementację operatora []
  4. czeka cię powtórka kroku nr 2, choć jedynie dla przypadków brzegowych. Jak nadal będzie dobrze znaczy to iż operator [] został zaimplementowany poprawnie.
  5. następny w kolejce jest operator=, tutaj uwaga - od razu sobie stwórz wersję dla przypisania double'a oraz innego wielomianu
  6. następny krok to implementacja operatora <<, podpowiedź - chcemy zobaczyć równanie wielomianu jakie zostało wprowadzone przy użyciu [ ] albo addPolyComponent(), generalnie zawartość wektora ładnie przerobioną na string.
  7. implementacja operatora * aby mnożyć wielomian z wielomianem, liczbę z wielomianem, i wielomian z liczbą. Dla ułatwienia przyjmij, iż liczba ma typ double
  8. na koniec pozostaje operator(). To zostawiam dla ciebie do wykazania się.
0

Mono nie poprawiłem, bo przerzucając kod na ubuntu przesłałem starszy kod i zapomniałem jeszcze raz go poprawić. Na windowsie niestety dev-c++ lekko mówiąc się zepsuł, a docelowo i tak powinienem się uczyć na ubuntu. Tylko, że opcja kopiowania rzeczy z windowsa do virtualboxa i z powrotem mi nie działa więc trochę to męczarnia, bo non stop muszę wrzucać gdzieś kod lub przesyłać mailem. A opcję współdzielenia schowka w obie strony mam zaznaczoną więc spytam po prostu profesora przy najbliższym spotkaniu co może być przyczyną.
Debuggera jeszcze nie używałem. Jedynie byliśmy zapoznani z opcją valgrind w celu sprawdzenia wycieków pamięci i tyle (wiem, że to nie ma nic wspólnego z debuggerem ale to tylko przykład tego co jest od nas wymagane.)

Zadanie mam do zrobienia na poniedziałek. Owszem - jestem zielony ale same idee klas i struktur itd. rozumiem, a nie programowałem po prostu za wiele programów wymagających te rzeczy. Jest to drugie zadanie z pisania klas dopiero, a zaliczeniem w przyszłości będzie napisanie właśnie programu z wykorzystaniem klasy.
Nie czuję się w tym temacie dobrze ale codziennie staram się coś nowego czytać i przyswoić.
Ok, może nie zdążę na poniedziałek tego zrobić ale chciałbym dalej iść do przodu i choćby to calculatePoly dobrze napisać.

Co do kolejnych punktów, które wypisałeś:

  1. Poprawiłem już Mono - dodałem connector
  2. Próbowałem poprawić kod tak żeby calculatePoly mi działało i żebym mógł sprawdzać czy wynik daje dobry -po kilku poprawkach UDAŁO SIĘ! :D
    Próbowałem dla wyższych liczb obliczać i wynik jest dobry.
    -x^3 - ( -0.33x^2) - 4x - 10 Nie rozumiem w którym momencie użytkownik mógłby doprowadzić do sytuacji w której by było - ( - coś) przy obecnym kodzie, bo tylko się podaje Multiplier, x i power. Mogłoby być -x^3 + (-1 * (ujemna wartość x)^2) itd. Chyba, że zaczniemy pytać użytkownika o connector i rozbudujemy obecną metodę calculatePoly i addPolyComponent. Dobrze mi się wydaje czy czegoś nie zauważam?

Jeśli chodzi o samo liczenie z wartościami typu 0.33 itd to liczy dobrze :)

Poly.cpp:

#include "Poly.h"

Poly::Poly(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Poly::Poly(const Poly &w) // copy
{
	n= w.n;
   	wsp= new double[n];
	for (int i=n; i>=0; i--)
   		{
       		wsp[i]=w.wsp[i];
   		}
}
 
// suma
Poly operator+(const Poly& A, const Poly& B)
{
	int n;
	
	if (A.n>=B.n)
	{
    	n=A.n;
	}
	
   else
	{
    	n=B.n;
	}
	
	Poly w(n);
	w.wsp = new double[w.n];
	for (int i=w.n; i>=0; i--)
	{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
	}
	return w;
}
// iloczyn
Poly operator*(const Poly& A, const Poly& B)
{
	Poly w(A.n+B.n);
	for (int i=0; i<=w.n; i++)w.wsp[i]=0;
	for (int i=0; i<=A.n; i++)
	{
   		for (int j=0; j<=B.n; j++)
		{
			w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
		}
	}
   return w;
}


 
//ostream do cout'a
//ostream& operator<<(ostream& o, const Poly& w)
//{
//tu nie wiem jeszcze co bêdzie

//}
 
int main()
{
	cout<< "Hello World" <<endl;
 
	Poly P1;
	P1.addPolyComponent(0.33, 2);
	P1.addPolyComponent(-0.33, 2);
	P1.calculatePoly(2);
    return 0;
}

Poly.h:

#include <iostream>
#include <vector>
using namespace std;
 
class Poly
{
private:
struct Mono //jednomian
{
    char connector;//wartość dodatnia to +, ujemna to -, zero to brak łącznika z poprzednikiem
    double multiplier; //mnożnik
    double power; //nie ma co sobie żałować na nazwie ^^
};
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
public:
    std::vector<Mono> polyComponents;
    Poly() = default;
    Poly(int _n);              // konstrktor
    Poly(const Poly& w);  // konstruktor kopiujacy
 
void addPolyComponent(double multiplier , double power)
{
    Mono mono;
    mono.multiplier = multiplier;
    mono.power = power;
 
    polyComponents.push_back(mono);
}
double calculatePoly(double x)
{
    unsigned int k=0;
    double all=0;
    for( k = 0; k < polyComponents.size(); k++ )
    {	
        
        int i=0;
	double result = 1.0;

	cout << "Poly Components size: " <<polyComponents.size() << endl;
        for (i=0; i<polyComponents[k].power; i++)
	{
	cout << "poly Components power " <<polyComponents[k].power << endl;
        result*=x;
	
	cout << "poly Components multiplier " <<polyComponents[k].multiplier << endl;
	cout <<"Wynik po obiegu: " << result << endl;
	}      
 	result*= polyComponents[k].multiplier;
	all+= result;
 	cout <<"Wynik: " << result << endl;
    }
	cout <<"Wynik ogolny: " << all << endl;
    return all;
}

 
	//Przeci¹¿one operatory
    friend Poly operator +(const Poly& A, const Poly& B); // +
    friend Poly operator *(const Poly& A, const Poly& B); // *
 
double operator()(double valueForX)  //double val = P1( 3.14 );
{
    return 1; //tu wartoæ twojego wielomian po podstawieniu valueForX
}    
};
2

(...)dev-c++(...)

O Swarogu, Trygławie, Welesie, Perunie, Mokoszy, Rujewicie i cały panteonie widzicie i nie grzmicie...
Bracie wiezaawieza, wybrałeś chyba najbadziewniejsze IDE dla C++. Zaprawdę powiadam ci, skołuj sobie coś dorzecznego jak Code::Blocks, Visual Studio Enterprise, Qt Creator z MinGW, ba chyba nawet notatnik++ lepiej by się sprawił.
Przy okazji i kwestia debuggera się wtedy rozwiąże.

  1. Poprawiłem już Mono - dodałem connector
  2. Próbowałem poprawić kod tak żeby calculatePoly mi działało i żebym mógł sprawdzać czy wynik daje dobry -po kilku poprawkach UDAŁO SIĘ!
    Próbowałem dla wyższych liczb obliczać i wynik jest dobry.

Znakomicie! Co do uczulenia na wartości ujemne chodzi o to, żeby nie wpaść w pułapkę jak się poprzestawia składniki wielomianu, np taki:
2x^3 - 3x^2 + x - 5 == -5 + x + 2x^3 - 3x^2
Że jest to zagadnienie istotne przekonasz się jak spróbujesz poradzić sobie z tworzeniem wielomianu P2 przy pomocy [ ]
Btw - funkcja addPolyComponent() nie wspiera connectora :]

Uwagi do calculatePoly()

  • link do cpp reference dostałeś, to obczaj tam cóż takiego robi funkcja pow() ;)
  • w pętlach for() zmienną służącą za licznik, a niepotrzebną po jej zakończeniu definiuje się wewnątrz, czyli np for (unsigned int k = 0; k < polyComponents.size(); k++) { tu k jest dostępne } a tu już nie.
  • czemu result ma na dzień dobry wartość 1.0? A jak jakiś użytkownik-wesołek wywoła sobie calculatePoly() na obiekcie, na którym jeszcze nie utworzył składników wielomianu wypełniając wektor polyComponents to co wtedy?:]

Ooookkay...cóż Bracie widzisz jak patrzysz na ten kawałem maina z zadania?:

  poly P1;              //Declare object representing polynomial P1
  P1[3] = 2; P1[1] = 3.6; P1[0] = 7;    //Specify coefficients of P1 = 2x^3 + 3.6x + 7
0

A no racja. Dopiero ogarnąłem, że P2 jest zmieniona kolejność. Nieźle to wyłapałeś :D Ja ciągle się sugerowałem tym P1, a że było w dobrej kolejności to uznałem, że drugie też tak będzie miało. No to trzeba będzie connectora użyć :D Racja!

  • pow() - poczytałem i podmieniłem w programie :) Dziękuję za takie porady!
  • deklarowanie w for - A no tak. Przyzwyczajenie z C mi zostało. Poprawiłem kod :)
  • result 1.0 - jak myślałem o funkcji to jakoś to mi ułatwiło sytuację. Po dodaniu pow() już chyba nie potrzeba więc wyzerowałem :)
poly P1;              //Declare object representing polynomial P1
  P1[3] = 2; P1[1] = 3.6; P1[0] = 7;    //Specify coefficients of P1 = 2x^3 + 3.6x + 7

Tworzymy P1 do klasy poly, który będzie naszym wielomianem i potem do P1 w "[ ]" wrzucamy potęgę, a po "=" mnożnik. Tworzy się tu pojedyńczo jednomiany, które razem tworzą wielomian.

Poprawione kody:
(zaraz edytuję)
Poly.cpp:

#include "Poly.h"

Poly::Poly(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Poly::Poly(const Poly &w) // copy
{
	n= w.n;
   	wsp= new double[n];
	for (int i=n; i>=0; i--)
   		{
       		wsp[i]=w.wsp[i];
   		}
}
 
// suma
Poly operator+(const Poly& A, const Poly& B)
{
	int n;
	
	if (A.n>=B.n)
	{
    	n=A.n;
	}
	
   else
	{
    	n=B.n;
	}
	
	Poly w(n);
	w.wsp = new double[w.n];
	for (int i=w.n; i>=0; i--)
	{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
	}
	return w;
}
// iloczyn
Poly operator*(const Poly& A, const Poly& B)
{
	Poly w(A.n+B.n);
	for (int i=0; i<=w.n; i++)w.wsp[i]=0;
	for (int i=0; i<=A.n; i++)
	{
   		for (int j=0; j<=B.n; j++)
		{
			w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
		}
	}
   return w;
}


 
//ostream do cout'a
//ostream& operator<<(ostream& o, const Poly& w)
//{
//tu nie wiem jeszcze co bêdzie

//}
 
int main()
{
	cout<< "Hello World" <<endl;
 
	Poly P1;
	P1.addPolyComponent(0.33, 2);
	P1.addPolyComponent(-0.33, 2);
	P1.calculatePoly(2);
    return 0;
}

Poly.h:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
 
class Poly
{
private:
struct Mono //jednomian
{
    char connector;//wartość dodatnia to +, ujemna to -, zero to brak łącznika z poprzednikiem
    double multiplier; //mnożnik
    double power; //nie ma co sobie żałować na nazwie ^^
};
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
public:
    std::vector<Mono> polyComponents;
    Poly() = default;
    Poly(int _n);              // konstrktor
    Poly(const Poly& w);  // konstruktor kopiujacy
 
void addPolyComponent(double multiplier , double power)
{
    Mono mono;
    mono.multiplier = multiplier;
    mono.power = power;
 
    polyComponents.push_back(mono);
}
double calculatePoly(double x)
{
    
    double all=0;
    for(unsigned int k = 0; k < polyComponents.size(); k++ )
    {	
        
        
	double result = 0;

	//cout << "Poly Components size: " <<polyComponents.size() << endl;
        for (int i=0; i<polyComponents[k].power; i++)
	{
		result=pow(x,polyComponents[k].power); 

	//cout << "poly Components power " <<polyComponents[k].power << endl;
	//cout << "poly Components multiplier " <<polyComponents[k].multiplier << endl;
	//cout <<"Wynik po obiegu: " << result << endl;
	}      
 	result*= polyComponents[k].multiplier;
	all+= result;
 	cout <<"Wynik jednomianu: " << result << endl;
    }
	cout <<"Wynik ogolny: " << all << endl;
    return all;
}

 
	//Przeciazone operatory
    friend Poly operator +(const Poly& A, const Poly& B); // +
    friend Poly operator *(const Poly& A, const Poly& B); // *
 
double operator()(double valueForX)  //double val = P1( 3.14 );
{
    return 1; //tu wartosc twojego wielomian po podstawieniu valueForX
}    
};
1

Tworzymy P1 do klasy poly, który będzie naszym wielomianem i potem do P1 w "[ ]" wrzucamy potęgę, a po "=" mnożnik. Tworzy się tu pojedyńczo jednomiany, które razem tworzą wielomian.

Znakomicie, dokładnie tak! Hmmmm, a czy my czasem szczęśliwym zbiegiem okoliczności nie stworzyliśmy funkcji budującej wielomian na podstawie jednomianów? ;)

A teraz mały hack odnośnie obliczania wielomianów. Mamy funkcję calculatePoly() która jak mówisz działa dobrze. Ale jak wiadomo, obliczanie wielomianu to obliczanie wartości składających się nań jednomianów,i dodawanie/odejmowanie ich od wspólnego wyniku. Zatem całość można zapisać w taki sposób:

double calculatePoly(double x)
{
    double result;
    //jeśli w polyComponents nic jeszcze nie ma to nie od rzeczy byłoby dać jakieś zabezpieczenie, np rzucić wyjątek. Ale, to pewnie cię czeka w innych zadaniach. Na razie to tylko sygnalizacja potencjalnego problemu i rozwiązania.
    for (const Mono &mono : polyComponents) //a pisałem aby się zapoznać z taką formą for-a ^^
    {
         result += mono.calculate(x);//ciebie czeka cię implementacja calculate() dla struktury Mono ;]
    }
    return result;
}
0

Dokładnie też o tym samym myślałem :D Super ^^

Co do twojego kodu to jestem jeszcze na etapie, że dobrze wiedzieć, że coś takiego jest ale żeby samemu o tym pomyśleć w tworzeniu programu to już szanse nikłe. Ale jak już zdobędę więcej doświadczenia to pewnie mózg będzie inaczej myślał i będę takie rzeczy stosować.

Trochę mi to zajęło ale doprowadziłem do sytuacji, że się kompiluje. Z tego co zrozumiałem to miałem zrobić funkcję calculate i dać ją do struktury Mono.

kod:

Poly.cpp (BRAK ZMIAN):



#include "Poly.h"

Poly::Poly(int _n) : n(_n + 1) // konstruktor
{
//        wsp= new double[n];
//        srand(time(NULL));
//        for (int i= n-1; i>= 0; ++i)
//        {
//                wsp[i] = rand() % 21;
//                wsp[i] -= 10;
//        }
}
Poly::Poly(const Poly &w) // copy
{
	n= w.n;
   	wsp= new double[n];
	for (int i=n; i>=0; i--)
   		{
       		wsp[i]=w.wsp[i];
   		}
}
 
// suma
Poly operator+(const Poly& A, const Poly& B)
{
	int n;
	
	if (A.n>=B.n)
	{
    	n=A.n;
	}
	
   else
	{
    	n=B.n;
	}
	
	Poly w(n);
	w.wsp = new double[w.n];
	for (int i=w.n; i>=0; i--)
	{
       w.wsp[i]=A.wsp[i]+B.wsp[i];
	}
	return w;
}
// iloczyn
Poly operator*(const Poly& A, const Poly& B)
{
	Poly w(A.n+B.n);
	for (int i=0; i<=w.n; i++)w.wsp[i]=0;
	for (int i=0; i<=A.n; i++)
	{
   		for (int j=0; j<=B.n; j++)
		{
			w.wsp[i+j]+= A.wsp[i] * B.wsp[j];
		}
	}
   return w;
}


 
//ostream do cout'a
//ostream& operator<<(ostream& o, const Poly& w)
//{
//tu nie wiem jeszcze co bêdzie

//}
 
int main()
{
	cout<< "Hello World" <<endl;
 
	Poly P1;
	P1.addPolyComponent(0.33, 2);
	P1.addPolyComponent(-0.33, 2);
	P1.calculatePoly(2);
    return 0;
}

Poly.h (Są zmiany):



#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
 
class Poly
{
private:
struct Mono //jednomian
{
    char connector;//wartość dodatnia to +, ujemna to -, zero to brak łącznika z poprzednikiem
    double multiplier; //mnożnik
    double power; //nie ma co sobie żałować na nazwie ^^

double calculate(double x) const
{
	double monoresult=0;
	

        monoresult=pow(x,power);
	monoresult*= multiplier;
    
    cout <<"Wynik jednomianu: " << monoresult << endl;
return monoresult;
}

};
 
   int n;                          // stopien wielomianu
   double *wsp;                    // wspolczynniki wielomianu
public:
    std::vector<Mono> polyComponents;
    Poly() = default;
    Poly(int _n);              // konstrktor
    Poly(const Poly& w);  // konstruktor kopiujacy
 
void addPolyComponent(double multiplier , double power)
{
    Mono mono;
    mono.multiplier = multiplier;
    mono.power = power;
 
    polyComponents.push_back(mono);
}




double calculatePoly(double x)
{
    double result;

    for (const Mono &mono : polyComponents) 
    {
         result += mono.calculate(x);
    }
    return result;
}

 
	//Przeciazone operatory
    friend Poly operator +(const Poly& A, const Poly& B); // +
    friend Poly operator *(const Poly& A, const Poly& B); // *
 
double operator()(double valueForX)  //double val = P1( 3.14 );
{
    return 1; //tu wartosc twojego wielomian po podstawieniu valueForX
}    
};

liczenie jest dalej poprawne więc chyba działa tak jak powinno.

1

Całkiem dobrze wyszło, ale w Mono::calculate(double x) ktoś tu wpadł w pułapkę nie uwzględnienia parametru Mono::connector :P tutaj podpowiedź - możliwa inna pułapka z const :]
Jak już poprawisz, to potestuj na wielomianach jakich wcześniej użyłeś do testów calculatePoly() i sprawdź, czy takie same wyniki otrzymasz. Poza tym powymyślaj parę wielomianów "złośliwych" (np podany wcześniej taki z samymi różnicami jednomianów) i obczaj czy liczy poprawnie dla wartości -X < -1, -1, 0, 1, X > 1.
Jak będzie dobrze to bierz się za operator [ ], jak go zrobić to już wiesz ^^

0

Nie żeby cokolwiek, ale takie rozwiązanie powoduje, że ciężko liczenie wartości wielomianu zrealizować efektywnie i poprawnie numerycznie, tj za pomocą schematu Hornera.

1

Nie mam pojęcia czemu ta dyskusja się tak rozwleka?
Temat powinien się zamknąć na jednej stronie (są już trzy).
Prawie gotowiec (jedno TODO):
https://wandbox.org/permlink/UL0b2Ja8VxvQEYZu

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