1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include <iostream>
#include <set>
#include <algorithm>
struct Term
{
size_t m_exponent;
double m_coefficient;
Term(const size_t exponent, const double coefficient) :
m_exponent(exponent), m_coefficient(coefficient){}
};
struct TermCompare//to use struct Term in std::set<Term>
{
bool operator ()(const Term& lhs, const Term& rhs)
{
return lhs.m_exponent < rhs.m_exponent;
}
};
using Order = std::set<Term, TermCompare>;//custom comparator for the set is TermCompare
struct PolyNom
{
Order m_factors;
PolyNom(){}
PolyNom(const Order& factors): m_factors(factors){}
double evaluate(const double& value)const;//evaluates value of polynomial expression for any double
PolyNom operator + ( PolyNom& rhs);
PolyNom operator - (const PolyNom& rhs);//implementation left as an exercise
PolyNom operator * (const PolyNom& rhs);
};
std::ostream& operator << (std::ostream& os, const PolyNom& p)//for printing
{
auto itr = p.m_factors.cbegin();
for (; itr != --p.m_factors.cend(); ++itr)
{
os << (*itr).m_coefficient << "X^" << (*itr).m_exponent << " + ";
}
for (; itr != p.m_factors.cend(); ++itr)//so that there is no + sign after the last term
{
os << (*itr).m_coefficient << "X^" << (*itr).m_exponent << "\n";
}
return os;
}
int main()
{
std::set<Term, TermCompare> a {{1, 2}, {3, 4.5}, {0,6}};
std::set<Term, TermCompare> b{{0,3}, {3,8}, {14, 6}, {9, 2}};
PolyNom p{a}, q{b};
std::cout << p << "\n";
std::cout << q << "\n";
std::cout << p.evaluate(7.5) << "\n";
auto pq = p * q;
std::cout << pq << "\n";
}
double PolyNom::evaluate(const double& value)const
{
double sum {};
for (const auto& elem: m_factors)
{
sum += (elem.m_coefficient) * std::pow(value, (elem.m_exponent));
}
return sum;
}
PolyNom PolyNom::operator + ( PolyNom& rhs)
{
PolyNom result{};
result.m_factors = m_factors;//first assign the terms of this object to terms of the result...
for ( auto elem : rhs.m_factors)
{
if(!result.m_factors.insert(elem).second)//... then if a particular term of the rhs cannot be inserted into result terms ...
//... it implies that exponent is already present in results ...
{
auto itr = std::find_if(result.m_factors.begin(), result.m_factors.end(), [&](const Term& t)
{return elem.m_exponent == t.m_exponent; }); // ... so find the term in results with the required exponent ...
auto temp = (*itr).m_coefficient; // ... save its coefficient
temp += elem.m_coefficient; // ... add in the coefficient from the rhs
result.m_factors.erase(itr); // now remove that term from the result's set of terms ...
result.m_factors.insert(Term(elem.m_exponent, temp)); // ... insert new term that has sum of coefficients of this and rhs
}
}
return result;
}
PolyNom PolyNom::operator * (const PolyNom& rhs)
{
PolyNom result{};
auto maxExponent = (*m_factors.crbegin()).m_exponent + (*rhs.m_factors.crbegin()).m_exponent;//max exponent
auto minExponent = (*m_factors.cbegin()).m_exponent + (*rhs.m_factors.cbegin()).m_exponent;//min exponent
for (auto i = minExponent; i <= maxExponent; ++i)// all other exponents from multiplication must fall b/w max and min exponent
{
double tempCoefficient{};
for (auto itr_this = m_factors.cbegin(); itr_this != m_factors.cend(); ++itr_this)
{
for (auto itr_rhs = rhs.m_factors.cbegin(); itr_rhs != rhs.m_factors.cend(); ++itr_rhs)
{
if((*itr_this).m_exponent + (*itr_rhs).m_exponent == i)// if we find a matching exponent ...
{
tempCoefficient += (*itr_this).m_coefficient + (*itr_rhs).m_coefficient;//... then record sum of corresponding co-efficients
}
}
}
if(tempCoefficient != 0)//i.e. some actual terms exists
{
result.m_factors.insert(Term(i, tempCoefficient));//then store the term in result
tempCoefficient = 0;
}
}
return result;
}
|