Pomoc ze zbudowaniem klasy – kilka pytań

0

Udało się! :D

Kod cały:


#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#include <typeinfo>
using namespace std;

class Poly
{
public:
    struct Mono
    {
        char sign = 1;
        double power;
        double multiplier;

        void operator=(double multiplier)
        {
        	this->multiplier = multiplier;
        }

    bool operator<(const Mono &other)
    {
        if (this->power == other.power)
        {
            if (this->multiplier == other.multiplier)
            {
                return this->sign > other.sign;
            }
            else
            {
                return this->multiplier > other.multiplier;
            }
        }
        else
        {
            return this->power > other.power;
        }
    }
		
	double calculate(double x);
	
    };
    
public:
Poly();
~Poly();
Poly(double multiplier);
friend ostream& operator<<(ostream& out, const Poly& d );
friend Poly operator+(const Poly &p1, const Poly &p2);

	

     void addPolyComponent(double multiplier , double power, char sign = 1)
    {

        Mono mono;
        mono.multiplier = (sign < 0 ? -multiplier : multiplier); //- (-Ax^Y)
        mono.power = power;
        mono.sign = sign;
 
        polyComponents.push_back(mono);
    }
void sortPoly()
{
    sort(polyComponents.begin(), polyComponents.end());
	
	
}

void reducePoly()
{
    if (polyComponents.size() <= 1)
    {
        return;
    }
 
    sortPoly();
 
    auto anchor = polyComponents.begin();
    auto search = anchor + 1;
 
    while (search != polyComponents.end())
    {
        if (search->power == anchor->power)
        {
            anchor->multiplier += search->multiplier;
            polyComponents.erase(search);
        }
        else
        {
            if (anchor->multiplier == 0)
            {
                polyComponents.erase(anchor);//to przestawia anchor i search o 1 w przód
                continue;
            }
            anchor = search;
            search++;
        }
    }
}

    
    Mono& operator[](double v)  //Do wyrazu wolnego, bo Poly P2 = 5  //Poly P2(5);
    {
        Mono mono;
        mono.power = v;
        mono.sign = 1;
        
        polyComponents.push_back(mono);
        return polyComponents.back();
    }

private:
    vector<Mono> polyComponents;
};




Poly::Poly() // konstruktor domyślny
{
}

Poly::~Poly() // destruktor
{
}

Poly::Poly(double multiplier) //konstruktor wywołujący addPolyComponent
{

	addPolyComponent(multiplier , 0, 0);
	

}

double Poly::Mono::calculate(double x)
{
double monoresult = 0;

monoresult = pow(x,power);
monoresult *= multiplier;

cout <<"Wynik jednomianu: " << monoresult << endl;

return monoresult;

}



ostream& operator<<(ostream &out,const Poly &poly)
{
    bool isFirst = true;
    for (const Poly::Mono &mono : poly.polyComponents)
    {
        if (!isFirst)//dla pierwszego elementu nie chcemy wyświetlać łącznika, jeśli jest ujemny to będzie pokazane przy multiplierze
        {
            out << (mono.sign >= 0 ? "+" : "") << mono.multiplier << "x^" << mono.power << " ";
        }
        else
        {
            isFirst = false;
            out << mono.multiplier << "x^" << mono.power << " ";
        }
    }
    return out;
}

Poly operator+(const Poly &p1, const Poly &p2)
{
    	Poly p3;
	p3.polyComponents = p1.polyComponents;
 	for (const Poly::Mono &mono : p2.polyComponents)
	{
		p3.polyComponents.push_back(mono);
	}
      
	p3.reducePoly();
    return p3;
}

int main()
{
    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
    return 0;
}

1

Hmmm....a weź dodaj do siebie wielomiany:
P4 = 2x^2 + 3x + 2
P5 = 3x^2 + 2x + 3
matematyk oczekiwałby, że wyjdzie 5x^2 + 5x + 5, dostaniesz wydruk swoim operatorem<< 5x^2 +5x^1 +5x^0 ? Podejrzewam, że nie :]

0

Kod mnożenia:



Poly operator*(const Poly &p1, const Poly &p2)
{
    	Poly p3; //p3 będzie sklejeniem wielomianów
	Poly p4; /p4 już będzie wynikowym wielomianem

//tutaj sklejam wielomiany i je sortuję
	p3.polyComponents = p1.polyComponents;
 	for (const Poly::Mono &mono : p2.polyComponents)
	{
			
	p3.polyComponents.push_back(mono);
	}
      
	p3.sortPoly(); //sortowanie żeby te same potęgi były obok siebie

//tutaj chcę żeby każdy kolejny element wielomianu był sprawdzany pod względem potęgi. Jak są równe to dodamy multiplier.
	for (const Poly::Mono &mono : p3.polyComponents)
	{
		if(mono.power == mono.power[i+1] (tutaj właśnie nie wiem jak to zapisać żeby była sprawdzona wartość kolejnego multi.power)
//no i tutaj będzie dodanie multiplier i pushback do p4
	
	}
	
    return p4;
}

0

Niestety, nie tędy droga. Nie zrozumiałeś idei stojącej za sklejaniem wektorów w celu dodawania wielomianów. Zobacz sobie przykład w linku, a szczególnie tą część po porzuceniu nawiasów => jak widzisz powstaje tak jakby nowy wielomian składający się z co istotne niezmodyfikowanej zawartości pierwszego i drugiego. Dlatego można było zrobić myk ze sklejeniem wektorów, po czym przeprowadzić redukcję.
Dobrze się wczytaj w ten przykład abyś potem profesorowi umiał wyjaśnić, skąd taka implementacja dodawania.

Z mnożeniem już nie jest tak prosto, sam sobie zobacz zamiast kopiować bez zastanowienia rozwiązanie z operatora dodawania. Podpowiem tutaj, iż życie może ułatwić implementacja:

Mono Mono::operator*(const Mono &other);
0
Poly operator*(const Poly &p1, const Poly &p2)// operator będzie wymagał zaprzyjaźnienia, a ta wersja dlatego, żeby obsłużył i mnożenie 2 * P1
{
//będzie potrzebny Poly do zwrócenia potem
     Poly p;

//mnożenie wielomianów polega na tym, że każdy składnik pierwszego wielomianu, czyli u nas Mono, trzeba pomnożyć przez każdy każdy składnik drugiego
//czyli przekładając to na kod tak:
    for (const Poly::Mono &mono1 : p1.polyComponents)
    {
        for (const Poly::Mono &mono2 : p2.polyComponents)
        {
              p.polyComponents.push_back(mono1 * mono2);//to wymaga implementacji operatora * dla Mono, to już Twoja działka :]
        }        
    }
//tutaj wielomian p trzeba będzie zgadnij co? :]
   
    return p;//i na końcu zwrócić go 
}
0
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#include <typeinfo>
using namespace std;

class Poly
{
public:
    struct Mono
    {
        char sign = 1;
        double power;
        double multiplier;

        void operator=(double multiplier)
        {
        	this->multiplier = multiplier;
        }

    bool operator<(const Mono &other)
    {
        if (this->power == other.power)
        {
            if (this->multiplier == other.multiplier)
            {
                return this->sign > other.sign;
            }
            else
            {
                return this->multiplier > other.multiplier;
            }
        }
        else
        {
            return this->power > other.power;
        }
    }

void operator*(const Mono &other) const
{
	this->power += other.power;
	this->multiplier *= other.multiplier;
	if(this->sign != other.sign)	
	{
	
		this->sign=-this->sign;	
	}
}


double calculate(double x);
	
    };
    
public:
Poly();
~Poly();
Poly(double multiplier);
friend ostream& operator<<(ostream& out, const Poly& d );
friend Poly operator+(const Poly &p1, const Poly &p2);
friend Poly operator*(const Poly &p1, const Poly &p2);
	

     void addPolyComponent(double multiplier , double power, char sign = 1)
    {

        Mono mono;
        mono.multiplier = (sign < 0 ? -multiplier : multiplier); //- (-Ax^Y)
        mono.power = power;
        mono.sign = sign;
 
        polyComponents.push_back(mono);
    }
void sortPoly()
{
    sort(polyComponents.begin(), polyComponents.end());
	
	
}

void reducePoly()
{
    if (polyComponents.size() <= 1)
    {
        return;
    }
 
    sortPoly();
 
    auto anchor = polyComponents.begin();
    auto search = anchor + 1;
 
    while (search != polyComponents.end())
    {
        if (search->power == anchor->power)
        {
            anchor->multiplier += search->multiplier;
            polyComponents.erase(search);
        }
        else
        {
            if (anchor->multiplier == 0)
            {
                polyComponents.erase(anchor);//to przestawia anchor i search o 1 w przód
                continue;
            }
            anchor = search;
            search++;
        }
    }
}

    
    Mono& operator[](double v)  //Do wyrazu wolnego, bo Poly P2 = 5  //Poly P2(5);
    {
        Mono mono;
        mono.power = v;
        mono.sign = 1;
        
        polyComponents.push_back(mono);
        return polyComponents.back();
    }

private:
    vector<Mono> polyComponents;
};




Poly::Poly() // konstruktor domyślny
{
}

Poly::~Poly() // destruktor
{
}

Poly::Poly(double multiplier) //konstruktor wywołujący addPolyComponent
{

	addPolyComponent(multiplier , 0, 0);
	

}

double Poly::Mono::calculate(double x)
{
double monoresult = 0;

monoresult = pow(x,power);
monoresult *= multiplier;

cout <<"Wynik jednomianu: " << monoresult << endl;

return monoresult;

}



ostream& operator<<(ostream &out,const Poly &poly)
{
    bool isFirst = true;
    for (const Poly::Mono &mono : poly.polyComponents)
    {
        if (!isFirst)//dla pierwszego elementu nie chcemy wyświetlać łącznika, jeśli jest ujemny to będzie pokazane przy multiplierze
        {
            out << (mono.sign >= 0 ? "+" : "") << mono.multiplier << "x^" << mono.power << " ";
        }
        else
        {
            isFirst = false;
            out << mono.multiplier << "x^" << mono.power << " ";
        }
    }
    return out;
}

Poly operator+(const Poly &p1, const Poly &p2)
{
    	Poly p3;
	p3.polyComponents = p1.polyComponents;
 	for (const Poly::Mono &mono : p2.polyComponents)
	{
		p3.polyComponents.push_back(mono);
	}
      
	p3.reducePoly();
    return p3;
}
Poly operator*(const Poly &p1, const Poly &p2) 
{

     Poly p;
 

    for (const Poly::Mono &mono1 : p1.polyComponents)
    {
        for (const Poly::Mono &mono2 : p2.polyComponents)
        {
              p.polyComponents.push_back(mono1 * mono2);
        }        
    }
p.reducePoly();
 
    return p;//i na końcu zwrócić go 
}

int main()
{
    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
    return 0;
}


błędy:

test.cpp: In member function ‘void Poly::Mono::operator*(const Poly::Mono&) const’:
test.cpp:44:23: error: assignment of member ‘Poly::Mono::power’ in read-only object
  this->power += other.power;
                       ^~~~~
test.cpp:45:28: error: assignment of member ‘Poly::Mono::multiplier’ in read-only object
  this->multiplier *= other.multiplier;
                            ^~~~~~~~~~
test.cpp:49:21: error: assignment of member ‘Poly::Mono::sign’ in read-only object
   this->sign=-this->sign;
                     ^~~~
test.cpp: In function ‘Poly operator*(const Poly&, const Poly&)’:
test.cpp:205:55: error: invalid use of void expression
               p.polyComponents.push_back(mono1 * mono2);
0

Ehhh...po pierwsze, toć w komentarzu dałem, iż deklaracja operatora * jako składnik klasy Mono ma być taka:

Mono operator*(const Mono &other) const

to do Peruna czemu się nie słuchasz, tylko jakieś

void Poly::Mono::operator*(const Poly::Mono&) const 

odwalasz?
Po drugie, operacje mnożenia jednomianów masz dobrze, ale nie należy robić tego na this, ale na tymczasowym nowym Mono zdefiniowanym wewnątrz, i ten nowy Mono, zawierający wynik mnożenia this * other zwrócić na zewnątrz.
Teraz jasne?

0
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#include <typeinfo>
using namespace std;

class Poly
{
public:
    struct Mono
    {
        char sign = 1;
        double power;
        double multiplier;

        void operator=(double multiplier)
        {
        	this->multiplier = multiplier;
        }

    bool operator<(const Mono &other)
    {
        if (this->power == other.power)
        {
            if (this->multiplier == other.multiplier)
            {
                return this->sign > other.sign;
            }
            else
            {
                return this->multiplier > other.multiplier;
            }
        }
        else
        {
            return this->power > other.power;
        }
    }

Mono operator*(const Mono &other) const
{
	Mono d;
	d.power =this->power + other.power;
	d.multiplier =this->multiplier * other.multiplier;
	return d;
}


double calculate(double x);
	
    };
    
public:
Poly();
~Poly();
Poly(double multiplier);
friend ostream& operator<<(ostream& out, const Poly& d );
friend Poly operator+(const Poly &p1, const Poly &p2);
friend Poly operator*(const Poly &p1, const Poly &p2);
	

     void addPolyComponent(double multiplier , double power, char sign = 1)
    {

        Mono mono;
        mono.multiplier = (sign < 0 ? -multiplier : multiplier); //- (-Ax^Y)
        mono.power = power;
        mono.sign = sign;
 
        polyComponents.push_back(mono);
    }
void sortPoly()
{
    sort(polyComponents.begin(), polyComponents.end());
	
	
}

void reducePoly()
{
    if (polyComponents.size() <= 1)
    {
        return;
    }
 
    sortPoly();
 
    auto anchor = polyComponents.begin();
    auto search = anchor + 1;
 
    while (search != polyComponents.end())
    {
        if (search->power == anchor->power)
        {
            anchor->multiplier += search->multiplier;
            polyComponents.erase(search);
        }
        else
        {
            if (anchor->multiplier == 0)
            {
                polyComponents.erase(anchor);//to przestawia anchor i search o 1 w przód
                continue;
            }
            anchor = search;
            search++;
        }
    }
}

    
    Mono& operator[](double v)  //Do wyrazu wolnego, bo Poly P2 = 5  //Poly P2(5);
    {
        Mono mono;
        mono.power = v;
        mono.sign = 1;
        
        polyComponents.push_back(mono);
        return polyComponents.back();
    }

private:
    vector<Mono> polyComponents;
};




Poly::Poly() // konstruktor domyślny
{
}

Poly::~Poly() // destruktor
{
}

Poly::Poly(double multiplier) //konstruktor wywołujący addPolyComponent
{

	addPolyComponent(multiplier , 0, 0);
	

}

double Poly::Mono::calculate(double x)
{
double monoresult = 0;

monoresult = pow(x,power);
monoresult *= multiplier;

cout <<"Wynik jednomianu: " << monoresult << endl;

return monoresult;

}



ostream& operator<<(ostream &out,const Poly &poly)
{
    bool isFirst = true;
    for (const Poly::Mono &mono : poly.polyComponents)
    {
        if (!isFirst)//dla pierwszego elementu nie chcemy wyświetlać łącznika, jeśli jest ujemny to będzie pokazane przy multiplierze
        {
            out << (mono.sign >= 0 ? "+" : "") << mono.multiplier << "x^" << mono.power << " ";
        }
        else
        {
            isFirst = false;
            out << mono.multiplier << "x^" << mono.power << " ";
        }
    }
    return out;
}

Poly operator+(const Poly &p1, const Poly &p2)
{
    	Poly p3;
	p3.polyComponents = p1.polyComponents;
 	for (const Poly::Mono &mono : p2.polyComponents)
	{
		p3.polyComponents.push_back(mono);
	}
      
	p3.reducePoly();
    return p3;
}
Poly operator*(const Poly &p1, const Poly &p2) 
{

     Poly p;
 

    for (const Poly::Mono &mono1 : p1.polyComponents)
    {
        for (const Poly::Mono &mono2 : p2.polyComponents)
        {
              p.polyComponents.push_back(mono1 * mono2);
        }        
    }
p.reducePoly();
 
    return p;//i na końcu zwrócić go 
}

int main()
{
    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
    return 0;
}

Wypisanie do konsoli:

Polynomial P1: 2x^3 +3.6x^1 +7x^0 
Polynomial P2: 5x^0 +3x^1 +6x^2 +1x^4 
Sum of polynomials P1 and P2: 1x^4 +2x^3 +6x^2 +6.6x^1 +12x^0 
Product of polynomials P1 and P2: 2x^7 +15.6x^5 +13x^4 +31.6x^3 +52.8x^2 +39x^1 +35x^0 
Polynomial P1 multiplied by 2: 4x^3 +7.2x^1 +14x^0 

To teraz pytanie jak zrobić ostatnią część:

  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
0

Ten wynik na pewno jest poprawny?:

Product of polynomials P1 and P2: 2x^7 +15.6x^5 +13x^4 +31.6x^3 +52.8x^2 +39x^1 +35x^0 
Polynomial P1 multiplied by 2: 4x^3 +7.2x^1 +14x^0 

Może daj mu dodatkowo do maina mnożenie jakiś prostych wielomianów w stylu 2x^2 + 3x + 1 * x^2 + 2

No i została ostatnia rzecz w mainie do zrobienia :]

  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

to już totalna prościzna, wystarczy przeimplementować operator() dla Poly, i wewnątrz tego operatora po prostu użyć calculatePoly(x) ^^

Zmykam wziąć kąpiel i ogolić się, więc masz jakieś 1.5h aby doimplementować ostatnią część i sprawdzić, czy mnożenie wielomianów działa prawidłowo

0

Mam problem.

1 opcja : calculate() jest w Mono. Jeśli dodaję do Mono funkcję double operator()(double valueForX) to błędy nie wyskakują od implementacji. Ale jak dodam kod z zadania do maina to wyskakują błędy.

2 opcja: Jeśli zamiast do Mono to poly dodam funkcję double operator()(double valueForX) do Poly to wyskakuje mi błąd "calculate() was not declared in the scope. Wrzucę Ci ten kod, bo jednak mniej błędów wyskakuje to może będzie łatwiej. Ale no ten błąd raczej wyskakuje dlatego, że calculate jest w Mono, a nasza funkcja nie.

Kod:

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#include <typeinfo>
using namespace std;
 
class Poly
{
public:
    struct Mono
    {
        char sign = 1;
        double power;
        double multiplier;
 
        void operator=(double multiplier)
        {
            this->multiplier = multiplier;
        }
 
    bool operator<(const Mono &other)
    {
        if (this->power == other.power)
        {
            if (this->multiplier == other.multiplier)
            {
                return this->sign > other.sign;
            }
            else
            {
                return this->multiplier > other.multiplier;
            }
        }
        else
        {
            return this->power > other.power;
        }
    }
 
Mono operator*(const Mono &other) const
{
    Mono d;
    d.power =this->power + other.power;
    d.multiplier =this->multiplier * other.multiplier;
    return d;
}
 
double calculate(double x);

 
    };
 
public:
Poly();
~Poly();
Poly(double multiplier);
friend ostream& operator<<(ostream& out, const Poly& d );
double operator()(double valueForX) ;
friend Poly operator+(const Poly &p1, const Poly &p2);
friend Poly operator*(const Poly &p1, const Poly &p2);
 
     void addPolyComponent(double multiplier , double power, char sign = 1)
    {
 
        Mono mono;
        mono.multiplier = (sign < 0 ? -multiplier : multiplier); //- (-Ax^Y)
        mono.power = power;
        mono.sign = sign;
 
        polyComponents.push_back(mono);
    }
void sortPoly()
{
    sort(polyComponents.begin(), polyComponents.end());
 
}
 
void reducePoly()
{
    if (polyComponents.size() <= 1)
    {
        return;
    }
 
    sortPoly();
 
    auto anchor = polyComponents.begin();
    auto search = anchor + 1;
 
    while (search != polyComponents.end())
    {
        if (search->power == anchor->power)
        {
            anchor->multiplier += search->multiplier;
            polyComponents.erase(search);
        }
        else
        {
            if (anchor->multiplier == 0)
            {
                polyComponents.erase(anchor);//to przestawia anchor i search o 1 w przód
                continue;
            }
            anchor = search;
            search++;
        }
    }
}
 
    Mono& operator[](double v)  //Do wyrazu wolnego, bo Poly P2 = 5  //Poly P2(5);
    {
        Mono mono;
        mono.power = v;
        mono.sign = 1;
 
        polyComponents.push_back(mono);
        return polyComponents.back();
    }
 
private:
    vector<Mono> polyComponents;
};
 
Poly::Poly() // konstruktor domyślny
{
}
 
Poly::~Poly() // destruktor
{
}
 
Poly::Poly(double multiplier) //konstruktor wywołujący addPolyComponent
{
 
    addPolyComponent(multiplier , 0, 0);
 
}
 
double Poly::Mono::calculate(double x)
{
double monoresult = 0;
 
monoresult = pow(x,power);
monoresult *= multiplier;
 
cout <<"Wynik jednomianu: " << monoresult << endl;
 
return monoresult;
 
}

double Poly::operator()(double valueForX) 
{
	double c;
	c = calculate(valueForX);      
	return c; //tu wartość twojego wielomian po podstawieniu valueForX
}
 
ostream& operator<<(ostream &out,const Poly &poly)
{
    bool isFirst = true;
    for (const Poly::Mono &mono : poly.polyComponents)
    {
        if (!isFirst)//dla pierwszego elementu nie chcemy wyświetlać łącznika, jeśli jest ujemny to będzie pokazane przy multiplierze
        {
            out << (mono.sign >= 0 ? "+" : "") << mono.multiplier << "x^" << mono.power << " ";
        }
        else
        {
            isFirst = false;
            out << mono.multiplier << "x^" << mono.power << " ";
        }
    }
    return out;
}
 
Poly operator+(const Poly &p1, const Poly &p2)
{
        Poly p3;
    p3.polyComponents = p1.polyComponents;
    for (const Poly::Mono &mono : p2.polyComponents)
    {
        p3.polyComponents.push_back(mono);
    }
 
    p3.reducePoly();
    return p3;
}
Poly operator*(const Poly &p1, const Poly &p2) 
{
 
     Poly p;
 
    for (const Poly::Mono &mono1 : p1.polyComponents)
    {
        for (const Poly::Mono &mono2 : p2.polyComponents)
        {
              p.polyComponents.push_back(mono1 * mono2);
        }        
    }
p.reducePoly();
 
    return p;//i na końcu zwrócić go 
}
 

int main()
{
    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
    return 0;
}

Błąd:

test.cpp: In member function ‘double Poly::operator()(double)’:
test.cpp:157:6: error: ‘calculate’ was not declared in this scope
  c = calculate(valueForX);
      ^~~~~~~~~

0

<facepalm> O Swarogu, Perunie, Trygławie i Welesie, czemu Ty na siłę sobie utrudniasz życie?
A metodę Poly::calculatePoly(double valueForX) to gdzie żeś posiał? To teraz jazda przeglądać 7 stron tego wątku żeby ją odnaleźć :]

0

kod:

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#include <typeinfo>
using namespace std;
 
class Poly
{
public:
    struct Mono
    {
        char sign = 1;
        double power;
        double multiplier;
 
        void operator=(double multiplier)
        {
            this->multiplier = multiplier;
        }
 
    bool operator<(const Mono &other)
    {
        if (this->power == other.power)
        {
            if (this->multiplier == other.multiplier)
            {
                return this->sign > other.sign;
            }
            else
            {
                return this->multiplier > other.multiplier;
            }
        }
        else
        {
            return this->power > other.power;
        }
    }
 
Mono operator*(const Mono &other) const
{
    Mono d;
    d.power =this->power + other.power;
    d.multiplier =this->multiplier * other.multiplier;
    return d;
}
 
double calculate(double x);

 
    };
 
public:
Poly();
~Poly();
Poly(double multiplier);
friend ostream& operator<<(ostream& out, const Poly& d );
double operator()(double valueForX) ;
friend Poly operator+(const Poly &p1, const Poly &p2);
friend Poly operator*(const Poly &p1, const Poly &p2);


 double calculatePoly(double x)
{
    double result;
 
    for (const Mono &mono : polyComponents) 
    {
         result += mono.calculate(x);
    }
    return result;
}
     void addPolyComponent(double multiplier , double power, char sign = 1)
    {
 
        Mono mono;
        mono.multiplier = (sign < 0 ? -multiplier : multiplier); //- (-Ax^Y)
        mono.power = power;
        mono.sign = sign;
 
        polyComponents.push_back(mono);
    }
void sortPoly()
{
    sort(polyComponents.begin(), polyComponents.end());
 
}
 
void reducePoly()
{
    if (polyComponents.size() <= 1)
    {
        return;
    }
 
    sortPoly();
 
    auto anchor = polyComponents.begin();
    auto search = anchor + 1;
 
    while (search != polyComponents.end())
    {
        if (search->power == anchor->power)
        {
            anchor->multiplier += search->multiplier;
            polyComponents.erase(search);
        }
        else
        {
            if (anchor->multiplier == 0)
            {
                polyComponents.erase(anchor);//to przestawia anchor i search o 1 w przód
                continue;
            }
            anchor = search;
            search++;
        }
    }
}
 
    Mono& operator[](double v)  //Do wyrazu wolnego, bo Poly P2 = 5  //Poly P2(5);
    {
        Mono mono;
        mono.power = v;
        mono.sign = 1;
 
        polyComponents.push_back(mono);
        return polyComponents.back();
    }
 
private:
    vector<Mono> polyComponents;
};
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
Poly::Poly() // konstruktor domyślny
{
}
 
Poly::~Poly() // destruktor
{
}
 
Poly::Poly(double multiplier) //konstruktor wywołujący addPolyComponent
{
 
    addPolyComponent(multiplier , 0, 0);
 
}
 
double Poly::Mono::calculate(double x)
{
double monoresult = 0;
 
monoresult = pow(x,power);
monoresult *= multiplier;
 
cout <<"Wynik jednomianu: " << monoresult << endl;
 
return monoresult;
 
}



double Poly::operator()(double valueForX) 
{
	double c;
	c = calculatePoly(valueForX);      
	return c; //tu wartość twojego wielomian po podstawieniu valueForX
}
 
ostream& operator<<(ostream &out,const Poly &poly)
{
    bool isFirst = true;
    for (const Poly::Mono &mono : poly.polyComponents)
    {
        if (!isFirst)//dla pierwszego elementu nie chcemy wyświetlać łącznika, jeśli jest ujemny to będzie pokazane przy multiplierze
        {
            out << (mono.sign >= 0 ? "+" : "") << mono.multiplier << "x^" << mono.power << " ";
        }
        else
        {
            isFirst = false;
            out << mono.multiplier << "x^" << mono.power << " ";
        }
    }
    return out;
}
 
Poly operator+(const Poly &p1, const Poly &p2)
{
        Poly p3;
    p3.polyComponents = p1.polyComponents;
    for (const Poly::Mono &mono : p2.polyComponents)
    {
        p3.polyComponents.push_back(mono);
    }
 
    p3.reducePoly();
    return p3;
}
Poly operator*(const Poly &p1, const Poly &p2) 
{
 
     Poly p;
 
    for (const Poly::Mono &mono1 : p1.polyComponents)
    {
        for (const Poly::Mono &mono2 : p2.polyComponents)
        {
              p.polyComponents.push_back(mono1 * mono2);
        }        
    }
p.reducePoly();
 
    return p;//i na końcu zwrócić go 
}
 

int main()
{
    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
    return 0;
}

błędy:

test.cpp: In member function ‘double Poly::calculatePoly(double)’:
test.cpp:71:36: error: passing ‘const Poly::Mono’ as ‘this’ argument discards qualifiers [-fpermissive]
          result += mono.calculate(x);
                                    ^
test.cpp:50:8: note:   in call to ‘double Poly::Mono::calculate(double)’
 double calculate(double x);

1

Do definicji i deklaracji Mono::calculate() musisz na końcu dopisać const;
Ach, i nie napisałem - calculatePoly() wygląda dobrze, użyj jej w operatorze ()

0

Ok, działa. Jutro mam nadzieję, że uda mi się ze wszystkiego ładnie wytłumaczyć :) I pewnie dostanę nowe zadanie więc będzie dalsza nauka i mam nadzieję, że lepiej mi to pójdzie i szybciej :D
Kod właśnie teraz porządkuje ;D

konsola wypisała:

Polynomial P1: 2x^3 +3.6x^1 +7x^0 
Polynomial P2: 5x^0 +3x^1 +6x^2 +1x^4 
Sum of polynomials P1 and P2: 1x^4 +2x^3 +6x^2 +6.6x^1 +12x^0 
Product of polynomials P1 and P2: 2x^7 +15.6x^5 +13x^4 +31.6x^3 +52.8x^2 +39x^1 +35x^0 
Polynomial P1 multiplied by 2: 4x^3 +7.2x^1 +14x^0 
Wynik jednomianu: 61.9183
Wynik jednomianu: 11.304
Wynik jednomianu: 7
Value of polynomial P1 at point 3.14: 80.2223

1

Rozumiem, że już się wszystko udało. Jak się wyśpisz to napisz @wiezaawieza czego się nauczyłeś przez te 2-3 dni zmagań z tym zadaniem.

2

Podsumowanie :D
Nauczyłem się:

  1. Że Dev-C++ jest gówniany i zainstalowałem code::blocks, chociaż nie podoba mi się styl programu i jak będę miał czas to trzeba będzie albo zmienić jego wygląd (w konsoli też sporo tekstu wyrzuca jak dla jednego błędu więc trochę mnie odrzucił). Za to konsola Ubuntu i notatniki tam mi się spodobały i same błędy są dosyć jasne jak dla mnie więc będę częściej korzystał.
  2. Polubiłem się z VirtualBox'em --> Ubuntu. Wcześniej ustawiłem mu za mało Ramu i procesorów i działał dosyć wolno, a podczas pracy nad tym zadaniem poświęciłem chwilę na naprawienie tego i teraz śmiga super. To też nauka dla mnie była :D
  3. Dowiedziałem się co to klasa, obiekty i jak się co robi, bo dopiero po napisaniu tematu na tym forum poszedłem o tym poczytać, a wcześniej byłem totalnie zielony. Z samych wykładów na studiach wyniosłem trochę wiedzy o przeciążaniu operatorów i w sumie niewiele więcej.
  4. Generalnie patrząc na maina już poszczególne rzeczy widzę, które powinny być na pierwszy rzut oka zaimplementowane. Jakie metody itd. A kolejne dochodzą w czasie pisania klasy jak czegoś potrzeba :D Już taki zielony nie jestem w tym :D
  5. Poznałem sam zamysł vectora chociaż wyrzucał pełno błędów podczas robienia zadania. Wiem tyle, że jest to taki plus, że nie trzeba się martwić wielkością vector'a bo on się tym sam zajmuje i to taki plus :D
  6. Wiem teraz, że metody najlepiej pisać poza klasą, a w samej klasie pisać tylko ich deklaracje, bo ułatwia to odczytywanie kodu itd. - Chociaż uważam, że łatwiej mi się było odnaleźć jak wszystko pisałem w jednym pliku i mieszałem pisanie metod - jedne w klasie, inne poza. No ale oddając program profesorowi rozdzieliłem to na dwa pliki i mimo, że zostawiłem kilka metod w klasie to się nie czepiał.
  7. Nauczyłem się jak poprawnie powinno się używać wcięć.
  8. Nauczyłem się, że powinno się używać nazw angielskich (niby to wiedziałem ale nigdy nie stosowałem, a teraz widzę, że to fajniej wygląda + łatwiej znaleźć w google pewne rzeczy jak mamy błąd kompilacji :D)
  9. Przypomniałem sobie działania na wielomianach i choć myślałem, że wszystko pamiętam to sprowadziłeś mnie na ziemię i pokazałeś, że mam korzystać ze stron matematycznych i przerobić jakieś przykłady
  10. Nauczyłem się odczytywać błędy z konsoli z którymi się wcześniej nigdy nie spotkałem i teraz już wiem jak na nie reagować. Np. proste [Error] no matching function for call to 'Wielomian::Wielomian()" z którym miałem problem na samym początku
  11. Nauczyłem się co to camelCase i mam nadzieję, że będę o nim pamiętał i w ten sposób zapisywał kilkuczłonowe nazwy
  12. Nauczyłem się poprawnego wrzucania kodu C++ na to forum tak żeby moderatorzy nie mieli przeze mnie za wiele roboty
  13. Pierwszy raz używałem for(coś : pojemnik) i potrafię taki kod teraz odczytać poprawnie, ale raczej boję się sam tego używać więc będę musiał się zmusić aż się poczuję w tym pewniej ;D
  14. Poznałem typ zmiennej "auto". Poznałem ale nie ogarniam jej za bardzo, bo jak raz chciałem użyć to sypało błędami więc to jeszcze do ogarnięcia będzie
  15. Spotkałem się kiedyś z funkcją pow() żeby podnieść coś do potęgi ale że to było dawno to zapomniałem o niej. Dobrze było sobie o niej przypomnieć :)
  16. Będę od teraz definiował iczniki w pętli for(int licznik), a nie przed jak to robiłem wcześniej - Większość programowania robiłem w C więc nawyk został ale będę korzystał z tego w C++, że tak można :)
  17. Poznałem co to konstruktor domyślny i trochę teorii na temat działania destruktora też
  18. Co do samego pisania nagłówków do funkcji / metod to czuję, że dalej mam problem. Wszystko wygląda zrozumiale jak już ten kod mam gotowy i zrobiony ale żeby ogarnąć to przed napisaniem kodu funkcji to zupełnie nie ogarniam czasem. Zdarzały się tutaj funkcje w których czułem, że mam przyjąć multiplier / power itd, bo funkcja będzie ich potrzebować ale w innych to czasami się dziwiłem, że w nagłówku nie ma przyjmowanego argumentu, a w środku funkcji mamy informację o jego wartości itd. Ale i tak już bardziej to ogarniam niż wcześniej :D
  19. Dowiedziałem się, że czasem poświęcenie czasu na zrobienie jednej dobrej funkcji jest warte zachodu żeby ją potem wykorzystać w innych funkcjach. Mówię tu o funkcji reducePoly, którą zrobiłeś i potem bardzo nam pomogła.
  20. Dowiedziałem się żeby używać cpp reference, bo to mój przyjaciel! :D
  21. Liznąłem iteratory, bo sam to raczej nie potrafię ich użyć jeszcze. Poczytałem, zobaczyłem kod i go ogarniam ale szczerze sam bym tego drugi raz poprawnie nie zrobił :/
  22. Dowiedziałem się, że jak jest metoda niestatyczna to mam ją używać zawsze dla jakiegoś obiektu żeby to działało. Niby podstawa, a nie znałem różnicy między statyczną, a niestatyczną w praktyce
  23. Co najważniejsze - Nauczyłem się tego wszystkiego od drugiej osoby i mam nadzieję, że w przyszłości sam będę dla kogoś mógł być kimś takim. Spora nauka dla psychiki :P

Bardzo za to wszystko dziękuję i postaram się tę wiedzę dalej wykorzystywać. Kolejne zadanie dostałem więc jutro napiszę temat z prośbą o pomoc. Tym razem mam nadzieję, że uda się skończyć zadanie w mniej niż 8 stron na tym forum chociaż każdy post i każde pytanie to była dawka wiedzy więc może i dobrze, że było mi dane móc się rozwijać przez tyle stron :D

0

Dzięki, miło poczytać, iż podejście dawkowania wiedzy przynosi owoce :) Jednak nadal rekomenduję zaopatrzyć się w "Opus Magnum C++" Jerzego Grębosza jeśli chcesz się zagłębiać w C++, bo z tego co widziałem wiedzę masz dosyć fragmentaryczną. A Grębosz np. ładnie opisuje i pojemniki, i iteratory ^^

Co do programu, to muszę tutaj wspomnieć o poważnej wadzie jakie mają reducePoly() oraz Mono::operator< - jest to porównywanie typów double poprzez operator == . Choć dane wejściowe na jakich oparte było zadanie powodowało, że wada ta nie ujawniła się w praktyce to wiedz, że tak robić nie należy, ale nie chciałem dodatkowo zawiłościami arytmetyki zmiennoprzecinkowej Ci zaciemniać sprawy. Aby poznać temat zapodaj w gógle "c++ double albo float comparison" oraz "c++ double/float representation/rounding error"

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