W
Und hier der gesammelte Source Code inklusive der Implementierung der Ausgabe von polynomial<> exklusiv "ctest.h"; letzteres scheinst Du ja geschafft zu haben.
#include "ctest.h" // s. http://www.c-plusplus.net/forum/p1828117#1828117
#include <iostream>
#include <vector>
template< typename T >
class polynomial
{
public:
polynomial()
: coeff_( 1, T() )
{}
polynomial& operator+=( const polynomial& b )
{
if( coeff_.size() < b.coeff_.size() )
coeff_.resize( b.coeff_.size() );
auto dst = begin(coeff_);
for( auto src = begin(b.coeff_); src != end(b.coeff_); ++src, ++dst )
*dst += *src;
return *this;
}
polynomial& operator-=( const polynomial& b )
{
if( coeff_.size() < b.coeff_.size() )
coeff_.resize( b.coeff_.size() );
auto dst = begin(coeff_);
for( auto src = begin(b.coeff_); src != end(b.coeff_); ++src, ++dst )
*dst -= *src;
return *this;
}
// -- die Funktionen für Einlesen&Ausgeben werden hier als 'friend' deklariert,
// so dass dort auf den private Member von polynomial<> zugegriffen werden kann
template< typename U > friend
std::ostream& operator<<( std::ostream& out, const polynomial< U >& p );
template< typename U > friend
std::istream& operator>>( std::istream& in, polynomial< U >& p );
private:
std::vector< T > coeff_;
};
// -- Funktion zum Lesen eines einzelnen Ausdrucks eines Polynoms
template< typename U >
std::istream& operator>>( std::istream& in, polynomial< U >& p )
{
U c;
int expo = 0;
if( in >> c ) // zunächst den Wert vor dem 'x' lesen
{
std::ios_base::fmtflags fmtflags = in.flags();
if( ctest( in >> std::noskipws, 'x' ) ) // Leerzeichen sind ab hier nicht gestattet; folgt ein 'x'?
{
expo = 1; // Ja, dann ist der Exponent =1, falls jetzt nichts mehr kommt
if( ctest( in, '^' ) ) // da kommt noch der Exponent
{
if( in >> expo ) // Exponent lesen
{
if( expo < 0 ) // neg. Exponenten nicht implementiert
in.setstate( std::ios_base::failbit );
}
}
}
in.flags( fmtflags );
std::vector< U > coeff( expo+1 );
coeff.back() = c; // Koeffizienten an die 'expo'-Stelle im Vektor schreiben, der Rest ist =0
swap( coeff, p.coeff_ ); // Ergebnis übernehmen
}
return in;
}
// -- Funktion zur Ausgabe des Polynoms
template< typename U >
std::ostream& operator<<( std::ostream& out, const polynomial< U >& p )
{
bool printed = false;
int expo = int(p.coeff_.size())-1;
for( auto c = p.coeff_.rbegin(); c != p.coeff_.rend(); ++c, --expo )
{ // Schleife läuft von rbegin nach rend, so dass die Koeffizienten mit den hohen Werten vorne stehen
if( *c == U() ) // *c == 0
continue; // Koeffizienten mit Wert =0 werden nicht ausgegeben
if( printed ) out << "+";
out << *c;
if( expo > 0 )
{
out << "x";
if( expo > 1 ) out << "^" << expo;
}
printed = true;
}
if( !printed )
out << U();
return out;
}
template< typename T >
class expression_type
{
public:
explicit expression_type( T& x ) : x_( x ) {}
T& x_;
};
template< typename T >
expression_type< T > expression( T& e )
{
return expression_type< T >( e );
}
// -- Funktion zum Einlesen eines expression_type< T >
template< typename T >
std::istream& operator>>( std::istream& in, expression_type< T > expr )
{ // expression = wert {("+"|"-") wert}.
for( in >> expr.x_; in; ) // den ersten Wert lesen; ..
{
if( ctest( in, '+' ) ) // ist es ein Plus?
{
T x2;
if( in >> x2 ) // .. dann 2.Wert lesen
expr.x_ += x2; // .. und addieren
}
else if( ctest( in, '-' ) ) // ist es ein Minus?
{
T x2;
if( in >> x2 ) // .. dann 2.Wert lesen
expr.x_ -= x2; // .. und subtrahieren
}
else
break; // weder '+' noch '-', dann fertig
}
return in;
}
int main()
{
using namespace std;
for( polynomial< double > poly; cin >> expression( poly ); cin.ignore( 999, '\n' ) )
cout << "die Eingabe: " << poly << endl;
return 0;
}
sei noch erwähnt, dass man das noch weiter vervollständigen kann.
So sollte polynomial<> eine Methode bekommen, die den höchsten Koeffizienten beseitigt, falls dieser =0 ist. Es fehlen auch noch die Funktionen um zwei Objekte zu addieren und zu subtrahieren. operator* wäre auch noch sinnvoll, usw.
Weiter wäre die Ausgabe noch zu verfeinern, so dass z.B. statt
3x+-5
besser
3x-5
ausgegeben wird.
Aber ich habe mich bemüht, den Code so einfach wie möglich zu halten.
Über ein Feedback würde ich mich freuen.
Gruß
Werner