Il s'agit d'écrire un programme permettant de réaliser des opérations sur les polynômes avec des coefficients rationnels. Vous devrez écrire une classe CRationnel pour gérer les coefficients et une CPolymone pour la gestion du polynôme dont le degré peut être quelconque. Cette classe devra contenu les quatre opérations de base (+, -, *, / ). Dans le programme principal, l'utilisateur pourra saisir des polynômes (nombre défini par l'utilisateur), puis sélectionner l'opération qu'il souhaite réaliser entre deux de ces polynômes. Le programme devra être convivial (utilisation de pointeurs, surcharge d’opérateurs, etc.).
Pouvez vous m'aider a faire cet exercice, je n'ai pas vraiment compris quoi mettre dans la classe CRationnel
Donc on te demande de faire une classe avec le nom CRationnel, certainement à sémantique de valeur, et sur cette classe de définir les 4 operations +, -, * et /. De plus, comme il t'est indiqué, il y a un invariant: le b doit être différent de zero.
Bon si tu relis ce que je viens d'écrire:
les 2 nombres a et b seront sûrement les variables membres de type entière,
Dans les créateur, il y a sûrement une précondition à vérifier, que b soit différent de zéro,
les 4 opération seront à écrire, et peut être aussi les fonction +=, -=, *= et /= (ça pourrait peut être être plus facile de commencé par ça)
Pour tes tests, il serai bon d'avoir une fonction "friend" pour faire la sortie sur cout << ;
Enfin, c'est ce que j'ai fait quand j'ai commencé le C++.
donc oui pour les valeurs a et b je pense faire comme vous me l'avez suggéré, cependant, il me faut plusieurs coefficient rationnel, je pensais les stocker dans un tableau et ensuite chercher chaque valeurs pour les opérations avec des pointeurs.
Et pour mes tests je vais donc surcharger l'opérateur d'extraction du flux mais pas celui d'incrémentation dans le flux(>>)?
Donc on te demande de faire une classe avec le nom CRationnel, certainement à sémantique de valeur, et sur cette classe de définir les 4 operations +, -, * et /. De plus, comme il t'est indiqué, il y a un invariant: le b doit être différent de zero.
On lui demande deux classes en fait.
- rationnels
- polynomes à coefficients rationnels.
Quant à la représentation interne des rationnels, il est raisonnable de stocker numérateur et dénominateur, avec bien sûr un dénominateur non nul, sinon ça n'a pas de sens, mais préférablement avec des coefficients réduits :
- b positif,
- a et b premiers entre eux.
Plutôt que de surcharger << (une manie des années 90), il est préférable de définir to_string() qui fournit une représentation de l'objet sous forme de texte.
Et il n'y a pas absoluement pas besoin de fonction "friend" pour ça. Si la représentation interne est normalisée (voir plus haut), l'utilisation d'accesseurs pour récupérer le numerateur et le dénominateur ne coûte rien, en pratique.
- Edité par michelbillaud 17 avril 2020 à 15:50:17
Je suis tout à fait d'accord, quand j'ai répondu, j'ai répondu à:
PaulKrd a écrit:
Pouvez vous m'aider a faire cet exercice, je n'ai pas vraiment compris quoi mettre dans la classe CRationnel
michelbillaud a écrit:
Plutôt que de surcharger << (une manie des années 90), il est préférable de définir to_string() qui fournit une représentation de l'objet sous forme de texte.
Ca c'est une bonne idée, j'y avait pas pensé ... et c'était pas dans l'exercice ... que j'avais fait, il y a ... bof ... pas si longtemps que ça! Mais en faisant une fonction membre to_string (), qui retourne un std::string, c'est encore mieux. Merci du tuyaux.
Bon, si on reprend:
Une classe CRationel (on l'a déjà décrit, et à raison, Michel nous fait remarquer qu'il faut la réduire, donc en plus il faudra sûrement une fonction privée, qui divise le m_num et le m_den par le PGDC, et que tu appels quand tu fait des opérations sur ton Rationnel [Je l'avais oublié celle là, on a la mémoire courte!])
et ensuite il te faut une autre classe, CPolynome. Cette classe, en effet, comme tu le dis, c'est un "tableau à taille variable" de CRrationnel. En C++ il y a un contenaire extraordinaire pour faire un tableau de taille variable ... pas besoin de pointeur, de new, ... Je te laisse chercher dans "containers library" de cette pages ou de celle ci, si tu ne sais pas, mais ça m'étonnerais, on l'utilise tout le temps!
Et ensuite je pense qu'il faut que tu réfléchisses comment on fait les 4 opérations (+, -, * et /) sur cette classe CPolynome (La aussi commence par le +=, le -= et le *=, j'ai pas réfléchi, et je ne sais pas si / et /= c'est possible, il y a sûrement des contraintes que je te laisserai chercher ... à la fin, commence par les autres c'est plus simple)
et pour faire des tests, une fonction membre to_string () ...
J'espère t'aider, Paul. Et merci de la remarque "to-string()" Michel.
Comme Michel et moi nous te l'avons dit, tu fais une class CRationnel, et ensuite une seconde class, CPolynome, qui contient un "tableau" de CRationnel. Tu fais un "tableau" de CRationnel, pas un tableau de Numérateur et de Dénominateur ...
Et quand je dis "tableau", regarde plutôt l'un des containers que je t'ai indiqué. Y-en à un super cool: redimensionnable, on peut y mettre n'importe quel élément dedans, ajouter, supprimer, adresser les élément en randum (c'est à dire tableau[x]), ...
Pourquoi as-tu besoin d'une boucle While ? Pour sortir d'une boucle while, il faut une condition de sortie ...
Maintenant, si tu te contentes de nous dire, "j'y arrive pas", je ne vais pas pouvoir beaucoup plus t'aider ...
As-tu compris ce que nous essayons de te faire trouver ? 2 classes différentes, l'une avec 1 rationnel, l'autre avec un "Tableau" de rationnel.
Bonjour Pierrot le fou,
Oui en effet, il y a une post condition, pour chaque fonction de cette classe CRationnel, la fraction doit être réduite! D'où l'utilisation d'une fonction de PGCD (on divise numérateur et dénominateur par le PGCD, c'est tous simple). Pour le calcule du PGCD, j'ai trouvé un algo récursif en 4 lignes.
De plus, comme tu l'indiques, c'est mieux de gérer le signe au numérateur, et d'avoir un dénominateur toujours positif. Là aussi, c'est une post condition.
J'ai maquetté tout ça cette après midi.
Mais pour l'instant, notre ami Paul doit avoir d'autres points à résoudre, mais je suis tout à fait d'accord avec toi, et je l'expliquerai à Paul en temps voulu.
Dans mon programme, j'ai d'abord demandé a saisir le rang du premier et du second polynôme que j'ai stocké dans des variables entière.
ensuite j'ai utilisé une boucle while pour saisir les valeurs des numérateurs et des dénominateurs pour de chaque coefficients, cependant, je n'arrive pas a incrémenter la fraction obtenue dans mon tableau (j'ai essayé d'utiliser "array" à la place d'un tableau de double sans grand succès..).
Dans ma boucle while il y a un if pour vérifier que le dénominateur est bien nul.
Pour écrire mon polynôme, j'ai créé une chaine de caractère string, cependant je ne peux pas additionner ni multiplier comme cela :
Polynome == m_pTab[i] * pow(X, i) + Polynome;
Je n'ai en fait pas bien compris ce que vous vouliez me dire, pour moi on nous demande de faire une classe de rationnel qu'on place dans 2 tableaux, 1 pour chaque polynôme et ensuite, dans une seconde classe utiliser ces tableaux pour réaliser les différentes opérations. Et finalement afficher le polynôme obtenu.
Puisque notre ami PaulKrd n'aime pas jouer aux devinettes, je vais jouer pour lui.
> il y a un contenaire extraordinaire pour faire un tableau de taille variable ... pas besoin de pointeur, de new, ... Je te laisse chercher dans "containers
> Et quand je dis "tableau", regarde plutôt l'un des containers que je t'ai indiqué. Y-en à un super cool: redimensionnable, on peut y mettre n'importe quel élément dedans, ajouter, supprimer, adresser les élément en randum (c'est à dire tableau[x]), ...
Ce n'est sûrement pas un des suivants: list, set, map car ils ne sont pas accessibles random.
Ce n'est pas array car il n'est pas redimensionable.
À moins que j'en ai loupé un, il nous reste le vectorr, je me trompe?
Le Tout est souvent plus grand que la somme de ses parties.
Plutôt que d'y aller, en séquence, je te propose d'y aller en approche POO (programmation orrienté objet)
c'est à dire, pour l'instant tu en es à: 1) je choisie le rand des polynômes, 2) je rentre chaque valeur du numérateur/dénominateur, 3) je les stock en string, 4) je fais l'opération, 5) j’affiche le résultat. (Je pense que tu ne vas pas y arriver.)
A la place, je te propose d'avoir une approche objet (ou encore service), comme c'est demandé. Si tu relis ton énoncé:
Il s'agit d'écrire un programme permettant de réaliser des opérations sur les polynômes avec des coefficients rationnels. Vous devrez écrire une classe CRationnel pour gérer les coefficients et une class CPolymone pour la gestion du polynôme dont le degré peut être quelconque. Cette classe devra contenir les quatre opérations de base (+, -, *, / ). Dans le programme principal, l'utilisateur pourra saisir des polynômes (nombre défini par l'utilisateur), puis sélectionner l'opération qu'il souhaite réaliser entre deux de ces polynômes [faire l'opération et afficher le résultat].
Ton programme, en effet, aura besoin de saisir 2 polynômes, de choisir 1 opérations, de réaliser cette opération entre les polynômes, et d'afficher le polynôme résultat.
Donc j'en déduis: Tu as besoin d'une class CPolynome, avec les services suivant: Création (ou saisie) d'un polynôme, opération + entre 2 polynômes, opération -, opération *, opération /, afficher un polynôme.
Un polynôme c'est quoi ? la représentation graphique c'est R0 + (R1 x) + (R2 x^^2) + (R3 X^^3) + .... (Rn X^^n) (avec n variable, et R0, R1, R2, R3, ... Rn, une suite de n rationnels). Dans tout ça les + et les X^^?, ça n'est que de la représentation graphique, ça n'apporte pas d’information ... donc au point de vue information, un polynôme, c'est une suite de de rationnel, dont le rand dans la suite est le rand dans le polynôme. C'est pour ça que je te propose de représenter ton polynôme par un "tableau" de rationnel, de taille variable, dans l'ordre croissant des rands.
Maintenant, si tu veux faire des opérations sur les polynômes, par exemple, l'addition pour 2 polynômes de rand 1: r0 + (r1 x) + s0 + (s1 x), ça va te donner: (r0 + s0) + ( (r1 + s1) x) ==> donc tu vas avoir besoin de l’addition entre des rationnels.
Et de même, pour les autres opérations entre les polynômes (je te laisse vérifier), tu auras donc aussi besoin des autres opérations entre les rationnels, le -, le * et le / .
De même, si tu veux afficher ton polynôme, il va falloir que tu affiches les coefficients de chaque rand ==> donc tu vas avoir besoin d'afficher des rationnels.
Tu en conclus donc, que pour faire ta classe CPolynône, tu as besoin d'une classe de CRationnel, avec les service suivant: création (ou saisie) d'un rationnel, opération +, -, * et / entre 2 rationnels, et l'affichage d'un rationnel.
Maintenant, c'est quoi un rationnel : C'est deux nombre entier, l'un qui s’appelle numérateur et l'autre dénominateur [et il y a quelque règles entre les deux: il sont premiers entre eux, le dénominateur est positif]
Ca y est ont est arrivé en bas! Maintenant tu sais ce que tu as à faire:
Une classe CRationnel, avec constructeurs, opération +, -, *, /, et sortie écran (Michel t'as proposé de faire une conversion en chaîne de caractères pour ça)
Une classe CPolynome, qui utilise la classe CRationnel, avec constructeurs, opération +, -, * et /, et sortie écran (ou plutôt) conversion chaîne de caractères.
un programme main () qui gère l'entré des polynôme et de l'opération, lance le calcule entre les polynôme, affiche le résultat.
Si on prend a = -2 et b = 4, les diviseurs communs sont -2, -1, 1 et 2. Si le terme "plus grand" a un sens, le pgcd(a,b), le plus grand des diviseurs, c'est 2.
Moi je partirais d'une observation apparemment sans grand intérêt qui est que les opérations sur des polynômes sont indépendantes de la nature de leurs coefficients. Du coup, plutôt que de me casser la tête sur une classe CPolynome liée à une classe CRationnel, je commencerais par me simplifier la vie en évacuant dans un premier temps les difficultés liées aux nombre rationnels pour me focaliser sur les opérations sur les polynômes avec un type de coefficient super simple: les entiers. De là je vais tirer un modèle de polynôme et si je me suis bien débrouillé, je n'aurais pas une classe Polynome utilisable uniquement avec des coefficients entiers, mais un modèle de classe Polynome utilisable avec n'importe quel type de coefficient (et si l'on pousse un peu plus loin, permettra de proposer une solution élégante et efficace au problème des polynômes creux évoqué par michelbillaud). Il ne restera donc plus qu'a construire ma classe CRationnel pour qu'elle puisse assumer le concept de coefficient de polynôme. Ce faisant, j'ai transformé mon problème à priori difficile, que je ne sais pas résoudre, en 2 problèmes plus faciles, que je sais résoudre.
De mes longues années de pratique, j'ai tiré une règle d'or à laquelle il ne faut jamais déroger: Ne jamais partir bille en tête, tout commence avec un bout de papier et un crayon, on commence par triturer le problème, pour essayer de le décomposer en problèmes plus simples, et c'est comme ça que l'ont résout le problème initial, en assemblant les solutions de problèmes sous-jacents plus simples. Comme dit le vieux proverbe: Diviser pour régner!
Je suis tout à fait d'accord avec toi. Si nous arrivons jusqu'à la fin avec Paul, en effet, il faudra transformer la classe CPolynome en une classe "Template". Bien sûr, Paul peut commence avec une classe Polynome de réel ... Mais vu ses première réponses, je ne suis pas sûr que ça va l'aider ... enfin, c'est à lui de choisir.
Dans mon post précédent j'ai essayé de lui montrer mon raisonement, et mon cheminement, mais bien sûr, il y en a d'autre, et pour ma part, je conprends très bien ton cheminement à toi.
Sauf que je n'ai jamais envisagé d'utiliser des réels, c'est bien trop compliqué pour mon petit cerveau Avec des entiers, c'est bien plus facile et ça marche très bien Le truc vraiment important est de bien découper le problème, tu as parlé de template, mais moi je n'en ai pas parlé (même si il y a un très gros sous-entendu, j'en conviens et que c'est effectivement vers là que je vais aller). L'idée qui est la mienne est vraiment le découpage, si je sais faire une addition de polynômes avec des coefficients entiers, alors je sais aussi la faire avec des coefficients rationnels, réel, ou même complexes, la seule difficulté qui reste est de définir pleinement le concept de coefficient. Là encore, je peux m'appuyer sur les points qui font qu'un entier représente le concept de coefficient, pour établir les règles qui vont me permettre de concevoir une représentation des rationnels qui remplira pleinement le concept de coefficient de polynôme. Je suis à des années lumières d'une implémentation, je suis toujours avec mon crayon et mon bout de papier...
> Sauf que je n'ai jamais envisagé d'utiliser des réels, c'est bien trop compliqué pour mon petit cerveau
J'ai peut-être manqué quelque chose, mais pourquoi parler de réels ici? Est-ce que tu faisais allusion aux coéfficients ou aux exposants de la variable des polynômes?
J'ai supposé qu'on avait des polynômes avec des exposants entiers et des coefficients d'un "certain type".
michelbillaud a parlé de termes "creux", s'il n'y en a pas beaucoup, il suffit de mettre les coefficients à 0 pour ces termes.
Il y a en effet deux problématiques:
+ comment fait-on l'arithmétique des polynômes? (addition, soustraction, multiplication, et division ? )
+ comment faire l'arithmétique des coeefficients? (addition, soustraction, multiplication, division)
Sauf pour la division, l'arithmétique des polynômes ne me semblais pas compliquée.
L'addition et la soustraction se font terme à terme (même puissance = même indice) attention si les puissances maximales ne sont pas les mêmes.
Pour la multiplication, la puissance maximale du produit est la somme des puissances des facteurs (polynômes).
Et pour les coefficients? J'ai sorti mon crayon et mon papier (ce texte)
disons pour la puissance 3, j'aurai la somme des coefficients 0,3 + 1,2 + 2,1 + 3,0
ce sera donc une boucle de 0 à 3 dont le second indice sera le "complément à 3" du premier.
et si je veux faire le produit d'un p3 par un p4 pour donner un p7 et je veux calculer le 5ième terme? Qu'à cela ne tienne ...
0,5 + 1,4 + 2,3 + 3,2 + 4,1 + 0,5
sauf que le premier est un p3 et le second est un p4, je dois restreindre les indices
1,4 + 2,3 + 3,2 pas plus ...
Les puissances 0 et 7 n'auront qu'un terme: 0,0 et 3,4
Je vous laisse en déduire la logique ...
Le Tout est souvent plus grand que la somme de ses parties.
J'ai le même programme à réaliser, je vous remercie déjà car vous m'avez pas mal aidé aussi , j'ai juste une petite question...
Dedeun a écrit:
Ca y est ont est arrivé en bas! Maintenant tu sais ce que tu as à faire:
Une classe CRationnel, avec constructeurs, opération +, -, *, /, et sortie écran (Michel t'as proposé de faire une conversion en chaîne de caractères pour ça)
Une classe CPolynome, qui utilise la classe CRationnel, avec constructeurs, opération +, -, * et /, et sortie écran (ou plutôt) conversion chaîne de caractères.
un programme main () qui gère l'entré des polynôme et de l'opération, lance le calcule entre les polynôme, affiche le résultat.
Ma classe CRationnel est parfaitement fonctionnelle, je n'ai pas encore fait CPolynome mais je comprend très bien comment je dois m'y prendre. Mon seul problème c'est que la consigne demande de faire saisir par l'utilisateur un nombre de polynômes qu'il aura choisi...
Pour moi on ne peut donc pas faire dans le programme main() quelque chose comme ça,
Quand j'ai écrit ça, Je voulais surtout expliqué à Paul de ne pas partir dans de la programmation séquentielle.
Commence par faire les 2 classes, et leur Test U.
Quand ça marche, alors tu fait une fonction main (). Dans la fonction main, il faut que tu entres 2 polynômes (donc éventuellement tu feras 1 procédure pour entré un polynôme et tu l'appels 2 fois !) et un opérateur (là aussi, tu peux faire une procédure qui boucle tant que l'on ne rentre pas le signe +, -, * ou /).
Pour entré un polynôme, déjà il faut que tu entres son rand (c'est à dire un chiffre positif, tant que c'est pas un chiffre positif, tu boucles en demandant un chiffre) puis ensuite pour chaque exposant, il faut que tu rentres le coefficient, un rationnel. c'est à dire un numérateur et un dénominateur (avec le contrôle que ce doivent être des nombres). Là encore ça doit pouvoir se découper en plusieurs fonctions, voir en une classes "saisieDUnEntier", enfin je ne sais pas je te laisse réfléchir, il faut bien que tu travail un peu, toi aussi!
J'espère t'avoir aidé!
Cordialement.
(PS: Euh, .... c'est pas moi le prof qui à donné cette exercice! Il attends peut-être quelque chose de différent! Mais si c'était moi l'étudiant (tient ça me rajeuni), c'est ce que j'aurais fait!)
Je ne pense pas que la démarche "tests unitaires" soit connue dans le genre de boutique où on propose encore ce type d'exercice des années 90.
En effet, tu as sûrement raison, ... Mais Paul ou Topinambour eux n'y sont pour rien. Je ne connais pas leur ambition, mais si un jour il se retrouve en SS2I, au moins une fois il auront entendu parlé de "TU". En tout cas, s'ils sont curieux, il peuvent chercher ce que ça veux dire. (Je ne fais qu'ouvrir des portes, je ne suis pas prof, moi!).
Remarque, c'est ce que j'ai fait un peu plus haut, 18 avril.
Comme quoi quand on en parle, y en a toujours qui n'écoutent pas :-)
- Edité par michelbillaud 25 avril 2020 à 10:20:03
Calculs de Polynomes
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.