Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
ENSIN2U1 - Programmation
TP 6
L’algorithme dit de Hörner, permet de calculer efficacement la valeur d’un polynôme. Nous allons
étudier cet algorithme, ce qui passe déjà par la question de la représentation d’un polynôme.
Considérons un polynôme P(x) = an xn + a n-1xn-1 +… a2 x2 + a 1 x + a0 dont les coefficients ai sont des
réels.
Donnez une structure de données C qui permet de représenter un polynôme. Il faudra pouvoir
mémoriser les coefficients ai et également le degré du polynôme. L’usage d’un type struct semble
bien adapté…
Reprendre une fonction de calcul de puissance que vous avez déjà programmée et, en l’utilisant,
écrivez une fonction qui, étant donnés un polynôme P et un réel x, évalue P(x). Vous testerez votre
fonction en affichant, en plus du résultat, le nombre d’additions et de multiplications de valeurs réelles
nécessaires à cette évaluation. Intégrez ces fonctions dans un programme (les coefficients d’un
polynôme sont saisis au clavier) et testez-les.
On peut disposer d’une méthode de calcul plus rapide. Elle repose sur les constats suivants :
P(x) =
an xn + a n-1xn-1 +… a2 x2 + a 1 x + a0 =
( an xn-1 + a n-1xn-2 +… a2 x + a1 ).x + a0 =
( ( an xn-2 + a n-1xn-3 +… a3 x + a2 ).x + a1 ).x + a0 =
( ( ( an xn-3 + a n-1xn-4 +… a3 ).x + a2 ).x + a1 ).x + a0 =
…
( (… ( ( an ).x + an-1 ).x+… +… a3 ).x + a2 ).x + a1 ).x + a0
De cette façon là, on évite les calculs répétés de puissances. En utlisant cette propriété, écrivez une
fonction qui, étant donnés un polynôme et un réel x, évalue P(x). Vous testerez votre fonction en
affichant, en plus du résultat, les nombres d’additions et de multiplications de valeurs réelles
nécessaires à cette évaluation. Intégrez votre fonction dans un programme et testez-la. Vous
comparerez les nombres d’additions et de multiplications de valeurs réelles avec celles nécessaires
pour la version naïve.
Une pile peut servir à l’évaluation d’une expression arithmétique. Nous simplifierons ici le problème
en supposant d’une part n’avoir affaire qu’à des petits nombres en entrée, correspondant aux 10
chiffres (0 à 9) et à des expressions bien parenthésées qui seront rentrées dans une chaîne de
caractères (non vide) de la forme suivante ((6*(5-(1+2)))+3)= où ‘ = ‘ précisera que
l’expression est terminée.
Pour évaluer cette expression, on va traiter chaque caractère de la suite en le lisant et en fonction de ce
qu’il représente, on adoptera des traitements adaptés :
- on empile pour le cas où le caractère est un chiffre ou un opérateur
- on procède au traitement suivant s’il s’agit d’une parenthèse fermante :
o on dépile l’élément au sommet (disons y),
o on dépile l’élément au sommet qui est un opérateur (disons op),
o on dépile l’élément au sommet (disons x),
o on réalise l’évaluation x op y
o on empile le résultat de l’évaluation précédente
- s’il s’agit d’une parenthèse ouvrante, on ne fait rien
- on dépile pour le cas où le caractère est ‘=’ ; la valeur dépilée est le résultat de l’évaluation
Pour l’exemple, on va empiler jusqu’au chiffre 2. La pile contiendra alors dans l’ordre [6*5-1+2].
Avec la parenthèse qui suit le chiffre 2, on dépile trois élements de sorte à obtenir x=1, op=+ et y=2.
On évalue le résultat 3, que l’on empile. On va ensuite dépiler trois élements de sorte à obtenir x=5,
op=- et y=3. On évalue le résultat 2, que l’on empile La pile contiendra alors dans l’ordre [6*2]. On
considère la parenthèse fermante, on dépile trois élements de sorte à obtenir x=6, op=* et y=2. On
évalue le résultat 12, que l’on empile. On va ensuite empiler + puis 3. Arrivé à la parenthèse fermante,
on dépile trois élements de sorte à obtenir x=12, op=+ et y=3. On évalue le résultat 15, que l’on
empile. On arrive alors à =. On dépile le seul élement de la pile, soit 15 qui est bien le résultat attendu.
Nous allons travailler avec des piles tabulaires. Avant cela, il faut donc définir les primitives associées.
#define MAX ... /* taille maximale de la pile */
typedef ... ELEMENT /* type des elements dans la pile */
typedef struct {
int sommet; /* indice du sommet de pile */
ELEMENT tab[MAX] ; /* tableau contenant les elements */
} PILE_TAB ;
Sur la base de ce qui vient d’être précisé, nous pouvons définir les différentes primitives réalisant la
gestion des objets définis dans le type :
- test de vacuité (est-ce que la pile est vide)
- test de saturation (est-ce que la pile est saturée)
- initialisation d’une pile à vide
- empiler
- dépiler
Dans cette première version, le type ELEMENT correspondra au type char et les éléments de la pile
seront à interpréter soit comme des entiers (pour le cas de chiffres) soit comme des opérateurs. Il vous
est demandé ici de programmer l’évaluation d’expressions arithmétiques selon la méthode décrite
dans l’introduction. Nous ne prendrons pas en compte la divsion.
Dans cette seconde version, le type ELEMENT peut être défini en expoitant les types de données de
nature union que nous présentons ci-dessous :
typedef union {
float v; /* pour représenter un réel */
char c; /* pour représenter un caractère */
} EXEMPLE ;
Ce type, identique à struct au niveau syntaxique pour la déclaration, fait coexister dans un
emplacement de la mémoire égal à la plus grande taille des champs (ici float ), une seule
information. Selon que l’on se réfère au champ v, il s’agira d’une valeur de type float , et si l’on se
réfère au champ c, il s’agira d’une valeur de type char. Ainsi, pourront coexister des éléments de
type float ou char. Les types de données de nature union peuvent permettre de gagner un espace
mémoire significatif pour le cas où les champs sont nombreux. Ce ne sera pas le cas ici.
Sachant que dans la pile, il s’agit de faire coexiter soit des nombres, soit des caractères (les
opérateurs), définissez un type ELEMENT adapté à ces circonstances et programmez à nouveau
l’évaluation d’expressions arithmétiques. Dans cet exercice, nous prendrons en compte les divsions et
il sera donc nécessaire de gérer des réels (même si pour les données en entrées, nous ne considérons
encore que les 10 chiffres 0 à 9). Enfin, notez qu’il ne faut pas modifier le code des primitives de
gestion de piles.