Polynomial Polynomial::operator*( Polynomial p )
{
    Polynomial res( "0" );

    int llen = coef->Len();

    for ( int l = 0; l < llen; ++l )
    {
        Polynomial pp( p );
        int rlen = pp.coef->Len();

        for ( int r = 0; r < rlen; ++r )
        {
            (*pp.coef)[ r ] *= (*coef)[ l ];
            (*pp.exp)[ r ] += (*exp)[ l ];
        }

        Polynomial temp( res + pp );

        delete res.exp;
        delete res.coef;

        res.exp = new Array< int >( *temp.exp );
        res.coef = new Array< float >( *temp.coef );
    }

    return res;
}
char *Polynomial::str()
{
    static char ret[ 1024 ];
    char *ret_ptr = ret;

    float coef_t;
    int exp_t;

    int len = coef->Len();

    for ( int i = 0; i < len; ++i )
    {
        coef_t = (*coef)[ i ];
        exp_t = (*exp)[ i ];

        if ( fabs( coef_t ) != 1 || exp_t == 0 )
        {
            ret_ptr = num2Str( coef_t, ret_ptr, i != 0 );
        }
        else
        {

            if ( coef_t < 0 )
            {
                *ret_ptr = '-';
                ++ret_ptr;
            }
            else if ( i != 0 )
            {
                *ret_ptr = '+';
                ++ret_ptr;
            }

        }

        if ( exp_t > 0 )
        {
            *ret_ptr = 'x';
            ++ret_ptr;

            if ( exp_t > 1 )
            {
                *ret_ptr = '^';
                ++ret_ptr;
                ret_ptr = num2Str( exp_t, ret_ptr );
            }

        }

    }

    ret_ptr = '\0';

    return ret;
}
float Polynomial::val( float x )
{
    float ret = 0;
    int len = coef->Len();

    for ( int i = 0; i < len; ++i )
    {
        ret += (*coef)[ i ] * pow( x, (*exp)[ i ] );
    }

    return ret;
}
Polynomial Polynomial::operator+( Polynomial p )
{
    Array< int > *res_exp = new Array< int >();
    Array< float > *res_coef = new Array< float >();

    int l = 0;
    int r = 0;
    int llen = coef->Len();
    int rlen = p.coef->Len();

    while ( l < llen || r < rlen )
    {
        float lcoef;
        float rcoef;
        int lexp;
        int rexp;

        if ( r == rlen )
        {
            lcoef = (*coef)[ l ];
            lexp = (*exp)[ l ];

            if ( lcoef != 0 )
            {
                res_exp->append( lexp );
                res_coef->append( lcoef );
            }

            ++l;

            continue;
        }

        if ( l == llen )
        {
            rcoef = (*p.coef)[ r ];
            rexp = (*p.exp)[ r ];

            if ( rcoef != 0 )
            {
                res_exp->append( rexp );
                res_coef->append( rcoef );
            }

            ++r;

            continue;
        }

        lcoef = (*coef)[ l ];
        rcoef = (*p.coef)[ r ];
        lexp = (*exp)[ l ];
        rexp = (*p.exp)[ r ];

        int cmp = lexp - rexp;

        if ( cmp > 0 )
        {
            res_exp->append( lexp );
            res_coef->append( lcoef );
            ++l;
        }
        else if ( cmp < 0 )
        {
            res_exp->append( rexp );
            res_coef->append( rcoef );
            ++r;
        }
        else
        {
            float coef_sum = lcoef + rcoef;

            if ( coef_sum != 0 )
            {
                res_exp->append( lexp );
                res_coef->append( coef_sum );
            }

            ++l;
            ++r;
        }

    }

    if ( res_exp->Len() == 0 )
    {
        res_exp->append( 0 );
        res_coef->append( 0 );
    }

    Polynomial res( "0" );

    delete res.exp;
    delete res.coef;

    res.exp = res_exp;
    res.coef = res_coef;

    return res;
}