Partage
  • Partager sur Facebook
  • Partager sur Twitter

fonction d'ajout de deux polynomes

22 mai 2007 à 20:19:04

bonjour svp quelqu'un pourrai maider a trouver mn erreur
voila ; pr limplementation de ma classe jai utiliser trois attributs der qui represente lindice du dernier ensemble,dim la taille maximale de mon vecteur et t qui lui est tableau de pointeur sur monome(je sais c'est pas tres interessant me bon je me devais de le faire,c'est ce qui mait demande)
me bon ds mon programme tout marche jusquau operateur +-*/%
la ca coince.je ne demande de laide que ds le +.
polynome& polynome::operator+(polynome &p)
               {polynome result(dim+p.dim);
                for(int i=0;i<=der;i++)   result+=(*(this->t[i]));
                for(int j=0;j<=p.der;j++) result+=(*(p.t[j]));
                return result;
                }

ici quqnd je fais un retour refernce de polynome,il maffiche un polynome nul.et quand je fais un retour sur polynome lexecution du programme se plante en plein milieu (envoyer rapport derreur a microsoft)

si quelqun peut me dire deja si ma fonction est fausse,sinon est ce aue jai respecte toute la syntaxe du c++.

merci d,avance pour votre aide.
  • Partager sur Facebook
  • Partager sur Twitter
22 mai 2007 à 20:51:31

J'aurais bien conseillé de faire d'abord l'opérateur += avant l'opérateur +, car c'est vraiment plus simple à faire, mais c'est une question de goût.

Je me demande sincèrement comment ton truc peut compiler : dans ta boucle tu utilise un opérateur bizarre dans ce style :
Polynome& Polynome::operator+=(const double);

Qui bien entendu ne veut rien dire.

J'ai rien compris à ton dim, der et ton tableau de monomes. (un monome étant un polynome, ton truc serait une sorte d'objet récursif : un suicide en somme)
C'est pourquoi je vais considérer que ton polynome possède un membre appelé 'deg' qui est son degré et que t est un tableau de double de taille deg+1, indexé par degré. Adapte à ton cas.
Essaye ça pour voir :

polynome& polynome::operator+ (polynome &p) {
    int r_deg = (deg > p.deg) ? dim : p.dim; // degré du résultat
    polynome result (r_deg); // résultat à la fin
    for(int i = 0; i <= deg ; ++i) result.t[i] += t[i];
    for(int i = 0; i <=p.deg; ++i) result.t[i] += p.t[i];
    return result;
}
  • Partager sur Facebook
  • Partager sur Twitter
22 mai 2007 à 21:35:58

oui jai deja defini loperateur += qui rajoute une monome a un polynome
voici mon code;
#ifndef DEF_MONOME
#define DEF_MONOME

#include <iostream>






struct monome
  {        float coef;
           int deg;
   
        monome(float icoef=0,int ideg=0);
        friend std::istream& operator>>(std::istream &in,monome &m);
        friend std::ostream& operator<<(std::ostream &out,monome &m);
        bool operator==(monome &m);
        bool operator!=(monome &m);
        bool operator<(monome &m);
        bool operator>(monome &m);
        bool operator<=(monome &m);
        bool operator>=(monome &m);
       
   
    };
#endif

             
 
   


#include"monome.h"
#include<cassert>
#include<iostream>

using namespace std;



                      // definitions des methodes


// constructeur de ma classe monome

            monome::monome(float icoef,int ideg):coef(icoef),deg(ideg){}

// pas besoin de redefinir le destructeur,la recopie et l`affectation
// les synthetises sont suffisants


// redefinitions  des flux d`entrees et sorties

             istream& operator>>(istream &in,monome &m)
                 {in>>m.coef;
                   cout<<"x"<<endl;
                   in>>m.deg;
                    return in;}


            ostream& operator<<(ostream &out,monome &m)
                 {out<<m.coef<<"x"<<m.deg;
                   return out;}
                 
// surcharge des operateurs

            bool monome::operator==(monome &m)
               {return deg==m.deg;}

            bool monome::operator!=(monome &m)
                { return deg!=m.deg;}

            bool monome::operator<(monome &m)
                { return deg<m.deg;}

            bool monome::operator>(monome &m)
                {return deg>m.deg;}

            bool monome::operator<=(monome &m)
                { return deg<=m.deg;}

            bool monome::operator>=(monome &m)
                {return deg>=m.deg;}
               
 
   
   
 


#ifndef DEF_POLYNOME
#define DEF_POLYNOME


#include "monome.h"






class polynome
  {        typedef monome* pmonome;
           int dim;
           int der;
           pmonome *t;
       public :
               
                 polynome(int idim=0,int ider=-1);
                 ~polynome();
                 polynome(polynome& p);
                 polynome& operator=(polynome& e);
                 bool polynomeplein();
                 bool polynomevide();
                 int localiser(monome& m);
                 polynome& operator+=(monome& m);
                 polynome& operator+(polynome &p);
                 polynome& operator-(polynome &p);
                 polynome& operator*(polynome &p);
                 polynome& operator/(polynome &p);
                 friend std::istream& operator>>(std::istream &in,polynome &p);
                 friend std::ostream& operator<<(std::ostream &out,polynome &p);
     };
#endif
#include"polynome.h"

using namespace std;








// definitions des methodes
               
// constructeur de ma classe polynome
            polynome::polynome(int idim,int ider):dim(idim),der(ider)
               {t=new pmonome[dim];
                for(int i=0;i<dim;i++)
                 t[i]= new monome;
                }
// destructeur de ma classe polynome
              polynome::~polynome()
                {    for(int i=0;i<dim;i++)
                         delete t[i];
                     delete[] t;
                 }
// definition de la fonction de recopie
              polynome::polynome(polynome& p):dim(p.dim),der(p.der)
                 {      t=new pmonome[dim];
                        for(int i=0;i<dim;i++)
                           { t[i]=new monome;
                           (*t[i])=*(p.t[i]);}
                   }
// surcharge de l`operateur d`affectaction

          polynome& polynome::operator=(polynome& e)
            { polynome test(e);
           
                der=test.der;
                dim=test.dim;
                swap(test.t,t);// je change juste les addresses

             return *this;}   

// definitions de deux fonctions tests polynomeplein,polynomevide
            bool polynome::polynomeplein()
              {return der==dim-1;}
             
            bool polynome::polynomevide()
               {return der==-1;}
               
// definition de la fonction localiser
// cette derniere retournera la position du monome sinon -1
 
             int polynome::localiser(monome& m)
                   {for(int i=0;i<=der;i++)
                       {if ((*t[i])==m)   
                          return i;}
                    return -1;
                    }   
// fonction d insertion dun monome


             polynome& polynome::operator+=(monome& m)
               {                     
                    int pos=localiser(m);
                    int i,j;
                    if (pos!=-1) t[pos]->coef+=m.coef;
                    else
             
                       
                    {    if (polynomeplein())
                             cout<<"ajout impossible"<<endl;
                         else
                         { for(i=0;i<=der&&(*t[i])<m;i++)   ;
                              for(j=der;j>=i;j--)
                                  (*t[j+1])=(*t[j]);
                              (*t[i])=m;
                              der++;
                         }
                       }     
                   
                        return *this;
                      }
                     
// redefinitions  des flux d`entrees et sorties
            istream& operator>>(istream &in,polynome &p) 
                {monome   m,zero(99,99);
                 in>>m;
                 while(m!=zero)
                   {p+=m;
                    in>>m;}
                  return in;
                  }
                 
            ostream& operator<<(ostream &out,polynome &p)
               {for(int i=0;i<=p.der;i++)
                  out<<*(p.t[i])<<"+";
                out<<"0"<<endl;
                return out;   
               }
               
               
//***************************************************************************
//polynome addition
           polynome& polynome::operator+(polynome &p)
               {polynome result(dim+p.dim);
                for(int i=0;i<=der;i++)   result+=(*(this->t[i]));
                for(int j=0;j<=p.der;j++) result+=(*(p.t[j]));
                return result;
                }
// polynome soustraction
                polynome& polynome::operator-(polynome &p)
                  {polynome result(der+p.der+10);
                   for(int i=0;i<=der;i++)   result+=(*t[i]);
                   
                   for(int i=0;i<=p.der;i++)
                        {monome temp(-(p.t[i]->coef),(p.t[i]->deg));
                         result+=temp;}
                   return result;
                   }
 
 // polynome multiplication
                  polynome& polynome::operator*(polynome &p)
                    {polynome result(t[der]->deg+(p.t[der])->deg+10,-1);
                      for(int i=0;i<=der;i++)
                        for(int j=0;j<=p.der;j++)
                          {monome temp(t[i]->coef*(p.t[j])->coef,t[i]->deg+p.t[j]->deg);
                           result+=temp;}
                        return result;
                        }
//polynome division
 /*           
                         polynome polynome::operator/(polynome &d)
                                  {polynome reste(*this);
                       while(reste.t[der]->deg>d.t[der]->deg)
{ monome m(reste.t[der]->coef/d.t[der]->coef,reste.t[der]->deg-d.t[der]->deg);
  polynome temp(5);temp+=m;
  polynome q(der);q+=m;
 
  monome m1(-m.coef,m.deg);
  temp+=m1;
  reste=(reste-(d*temp));
}
return q;


polynome polynome::operator%(polynome &d)
                                  {polynome reste(*this);
                       while(reste.t[der]->deg>d.t[der]->deg)
{ monome m(reste.t[der]->coef/d.t[der]->coef,reste.t[der]->deg-d.t[der]->deg);
  polynome temp(5);temp+=m;
  polynome q(der);q+=m;
 
  monome m1(-m.coef,m.deg);
  temp+=m1;
  reste=(reste-(d*temp));
}
return reste;

 



*/



     

#include "polynome.h"
 
 using namespace std;



int main()
{
   
    polynome p(3),q(3),w(20);monome m;
 cout<<"donne p"<<endl;
 cin>>p;
 cout<<p<<endl;
 cin>>q;
 cout<<q<<endl;
 cout<<"monome"<<endl;
 cin>>m;
 q+=m;
 cout<<q;
 
 
  w=p+q;
  cout<<w;
 
    system("PAUSE");
    return 0;
}
  • Partager sur Facebook
  • Partager sur Twitter
22 mai 2007 à 23:19:29

Manque plein de const. En fait tous.

De manière générale, on préfère systématiquement définir libre l'opérateur X() grâce à l'opérateur membre X=() -- oui je contredis la version courante du tuto de mathéo.

Seulement, dans ton cas cela voudrait dire que tu doives être redimensionnable. Avec un pointeur géré à la main, c'est pas gagné. Si ce n'est pas un exo pour un prof, cela se fait tout seul avec un vecteur -- ce genre d'exo est d'ailleurs la parfaite occasion d'apprendre à se servir de ce type de base du C++.

Ta structure creuse est assez bizarre. Je n'ai pas l'habitude de croiser ce genre de polynômes. Dans certains cas cela sera plus efficace, dans d'autres non. Cela doit pouvoir apporter de la souplesse, mais complexifie certaines opérations.

EDIT: Au fait.Ne jamais renvoyer de référence/pointeur sur des variables locales.
  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
23 mai 2007 à 1:17:57

encore une fois merci lmghs pour ton aide,
si je ne dois jamais renvoyer de reference sur des variables locales,comment pourrai je renvoyer l'addition de ces deux polynomes?



une idee qui vient de me passer par la tete mais elle est fausse:
je pense a rajouter le polynome resultat comme parametre ds ma fonction mais la je crois que cest impossible vu que le plus est un operateur binaire.


au lieu du + jai surcharge le += et donc je retourne cette fois le this(comme tu la dit) et ca a marcher.
meme si ce pas ce que je veux.
  • Partager sur Facebook
  • Partager sur Twitter
23 mai 2007 à 1:35:22

En fait pour pouvoir se permettre de faire un vrai opérateur +, *, etc, il faut avoir un constructeur de copie :
Type::Type(const Type&);
Que le compilo appellera automatiquement quand tu essaye de copier un objet de type Type. (passage par valeur)

A partir de là, tu fais les opérateurs d'affectations +=, *=...

Ensuite, tu fais +, * etc très simplement :
const polynome operator + (const polynome& a, const polynome& b) {
    polynome c (a);
    c += b;
    return c; // passage par valeur, constructeur de copie
}


Et hop :)

Pour le += si tu l'as déjà fais et qu'il marche, tout fonctionne, c'est super
  • Partager sur Facebook
  • Partager sur Twitter
23 mai 2007 à 1:43:05

Renvoie par recopie de la valeur. Le seul truc nécessaire, c'est que ton constructeur de copie soit correctement défini -- ce qui me parait être ton cas.

Il y a quand même un truc qui me perturbe. Ta structure n'est pas vraiment creuse.
Pourquoi ne pas avoir un "Monome*" au lieu d'un "Monome**" vu comment tu t'en sers? De fil en aiguille, un simple "double *" fait en fait l'affaire ... jusqu'au moment où tu veux partir sur la possibilité d'avoir des creux.

(Je ne me souvenais pas que ce problème nécessitait des choix de design pas nécessairement triviaux)
  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
23 mai 2007 à 1:50:30

Pour un polynome très creux, utiliser un map<unsigned,double> pour les coefficients peut être vraiment terrible. Sinon c'est clair que comme c'est présenté, y'a redondance de données et un simple double* alloué avec new[] suffirait amplement - ou un vector, pratique pour pas se fouler dans les += coté redimensionnement du tableau.
  • Partager sur Facebook
  • Partager sur Twitter
23 mai 2007 à 2:08:26

je sais que jaurai pu faire un de type monome* ou bien vecteur<monome>,list<monome>...
mais que faire cest ce qui nous ai demande.
jai pas compris:renvoie par recopie
je vois pas comment
  • Partager sur Facebook
  • Partager sur Twitter
23 mai 2007 à 2:11:00

Cf la réponse de Nilat sur le comment on renvoit par recopie de la valeur.
  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
23 mai 2007 à 2:47:27

je lai fait et jai renvoyer la valeur par copie
mais en plein milieux de lexecution le programme s'est interrompu brusquement pr le petit message de windows(polynome_tp.exe has encoutered a problem and needs to close.we are sorry for inconvenience)
aussi si je renvoie par recopie result,joblige mon ce dernier a avoir la meme dimension que celui recopie
et la ca me posera probleme
Non?
  • Partager sur Facebook
  • Partager sur Twitter
23 mai 2007 à 11:05:51

Bon alors t'as probablement une segfault quelque part, ce qui signifie simplement que tu écris là où il faut pas.
Avec des tableaux créés dynamiquement, ça arrive souvent.
Montre le code de ta classe, sans ça aucun moyen de voir où ça peut être.
  • Partager sur Facebook
  • Partager sur Twitter
23 mai 2007 à 14:36:02

jai deja poste mon code(voir plus haut)
  • Partager sur Facebook
  • Partager sur Twitter