2010-03-11 18 views
3

J'essaie d'utiliser la surcharge de l'opérateur pour définir les opérations de base (+, -, *, /) pour ma classe polynomiale mais lorsque je lance le programme, elle tombe en panne.Opérations polynomiales utilisant la surcharge de l'opérateur

Update4

Ok. J'ai réussi trois opérations, il ne reste plus que la division.

Voici ce que je suis:

polinom operator*(const polinom& P) const 
{ 
    polinom Result; 
    constIter i, j, lastItem = Result.poly.end(); 
    Iter it1, it2, first, last; 
    int nr_matches; 

    for (i = poly.begin() ; i != poly.end(); i++) { 
     for (j = P.poly.begin(); j != P.poly.end(); j++) 
       Result.insert(i->coef * j->coef, i->pow + j->pow); 
    } 

    Result.poly.sort(SortDescending()); 

    lastItem--; 

    while (true) { 
     nr_matches = 0; 

     for (it1 = Result.poly.begin(); it1 != lastItem; it1++) { 
      first = it1; 
      last = it1; 
      first++; 
      for (it2 = first; it2 != Result.poly.end(); it2++) { 
        if (it2->pow == it1->pow) { 
         it1->coef += it2->coef; 
         nr_matches++; 
        } 
      } 

      nr_matches++; 
      do { 
       last++; 
       nr_matches--; 
      } while (nr_matches != 0); 

      Result.poly.erase(first, last); 
     } 
     if (nr_matches == 0) 
      break; 
    }  

    return Result; 
} 
+0

Il devient tout à fait une autre question après la modification.Je ne comprends pas très bien comment la boucle peut se terminer maintenant que vous ne laissez jamais les itérateurs devenir égaux à la fin. – UncleBens

+0

J'ai compris pourquoi il bloque, c'est parce qu'il insère 3x^2 jusqu'à ce qu'il manque de mémoire et plante mon ordinateur. Maintenant, pour voir comment le réparer. – Vlad

+1

Votre "dernière" fonction ne retourne rien. Cela pourrait causer un problème. –

Répondre

1

pour ce qui est d'obtenir la fonction ajouter correctement des polynômes, je vous recommande cette logique simple:

polinom operator+(const polinom& P) const //fixed prototype re. const-correctness 
{ 
    polinom Result; 
    std::list<term>::const_iterator //fixed iterator type 
     i = poly.begin(), j = P.poly.begin(); 

    while (i != poly.end() && j != P.poly.end()) { 
     //logic while both iterators are valid 
    } 

    //handle the remaining items in each list 
    //note: at least one will be equal to end(), but that loop will simply be skipped 

    while (i != poly.end()) { 
     Result.insert(i->coef, i->pow); 
     ++i; 
    } 

    while (j != P.poly.end()) { 
     Result.insert(j->coef, j->pow); 
     ++j; 
    } 

    return Result; 
} 

La dernière partie peut probablement être laissée aux fonctions de la bibliothèque standard

#include <iterator> 
#include <algorithm> 

//... 
    //handle remaining items in either list (if any) 
    std::copy(i, poly.end(), std::back_inserter(Result.poly)); 
    std::copy(j, P.poly.end(), std::back_inserter(Result.poly)); 

... mais serait probablement plus simple en utilisant list.insert:

 Result.poly.insert(Result.poly.end(), i, poly.end()); 
    Result.poly.insert(Result.poly.end(), j, P.poly.end()); 
+0

En utilisant ce que vous venez de poster il se bloque à n'importe quelle entrée et aussi si je les insererais comme ça, il ne serait pas commandé du plus haut degré au plus bas. – Vlad

+0

Aussi à quoi sert la boucle vide? – Vlad

+0

Cette boucle vide est pour ** vous ** à remplir :) (fondamentalement le code que vous aviez déjà, sans l'obfuscation dans une tentative de faire tout le travail). – UncleBens

2

Il y a d'autres problèmes de conception et avec exactitude votre code, mais je pense que l'accident se produit dans cette ligne

if (i->pow > P.i->pow)

quand je == poly.end() & & Pi! = P.End() ou i! = Poly.end() & & Pi == P.End(). Déréférencement je quand il pointe après le dernier élément va planter.

5
while (i != poly.end() || P.i != P.End()) 

Je pense que vous aurez besoin & il &, sinon la boucle se termine que si i et p.i atteignent leur extrémité respective en même temps.

La logique avec des négations est délicate. Probablement plus simple de penser à ce que:

while (!(i == poly.end() || j == P.End())) //while neither iterator has reached end 

qui, selon l'arithmétique booléenne est le même que:

while (!(i == poly.end()) && !(j == P.End())) 
while (i != poly.end() && j != P.End()) 

Vous ne semblez pas être aussi incrémenter les itérateurs si les deux sont égaux (boucle infinie menant à une infinité d'allocations de mémoire?).


Problèmes de style: il vaut mieux utiliser des itérateurs comme variables locales. Ne faites pas de membres de classe variables s'ils sont supposés être "initialisés" avant de les utiliser dans une méthode, et ils deviennent inutiles une fois la méthode terminée.

préfèrent également passer des arguments par référence const, et marquer les fonctions membres const si elles ne modifient pas l'objet courant (operator+ ne devrait pas):

polinom operator+(const polinom& P) const; 

(qui révélerait le problème faisant localement ! d'occasion les membres de itérateurs - vous seraient en train de modifier les instances)

+0

+1 pour les problèmes de style. Un meilleur style conduit à une meilleure programmation :) – neuro

+0

Donc je devrais me débarrasser de SetIterBegin()? – Vlad

+0

Oui, c'est inutile aussi. – UncleBens