version avec corrigé

Transcription

version avec corrigé
TD 2
Structures de données
TD 2 : Structures de données
Octobre 2011
Après avoir vu comment calculer des choses simples numériquement ou formellement,
nous allons nous intéresser aux structures de données complexes et au bases de la programmation en Maple.
Types de données
Une commande dans Maple est une tapée sous forme de chaine de caractères. Le polynôme x2 − 1 est représenté par le mot “x^2-1”. Lorsque l’on tape une ligne en Maple, celle-ci
est ensuite interprétée : Maple transforme la ligne tapée en un ensemble de données qu’il va
pouvoir traiter.
Afin de mieux représenter en mémoire ces données, celles-ci sont classées en plusieurs
“types”. Chaque type représente une brique de base permettant de construire des expressions
beaucoup plus complexes.
La commande whattype(. . .) permet de connaitre le type d’une expression. Appliquée
à une expression simple, elle renvoie le type de l’expression en question ; appliquée à une
expression composée, le type de l’opération de plus haut niveau (celle de plus basse priorité).
Les types sont très variables : types numériques (integer, float, fraction, . . .), algébriques
(+, *, ˆ), d’égalités (= , <>, <=) relations logiques, . . .
Exercice 1
Quel
–
–
–
–
est le type des expressions suivantes ?
Types numériques : 3 ; 4.2 ; 113/3 ; I
Types algébriques : x + y ; x − y ; x ∗ y ; x/y ; xy
Relations logiques : (A or B) ; (A and B) ; (not A)
Autres : sin(x) ; (proc(x) x^2 ; end) ; 2..8 ; ’x’ ; ”sardine” ; Pi ; evalf(Pi)
Suites et Listes
Les suites et les listes sont deux façons de ranger plusieurs éléments ensemble en Maple.
Bien que se ressemblant beaucoup, elles n’ont pas le même usage.
Les Suites
Une suite est simplement un ensemble fini d’éléments donnés dans l’ordre, séparés par
des virgules.
Exercice 2
Quel est le type d’une suite ?
On peut assigner rapidement plusieurs variables grâce aux suites.
> p,q,r := 34, evalf(Pi), 2.5;
p, q, r := 34, 3.141592654, 2.5
> # Lorsqu’il y a plusieurs solutions le résultat de la commande solve est une liste.
racine1, racine2, racine3 := solve (x^3+x^2+x+1,x);
racine1, racine2, racine3 := -1, I, -I
> racine3;
-I
[email protected]
1
pauldcsimon.net
TD 2
Structures de données
Les Listes
Une liste est juste une suite entourée de crochets.
Exercice 3
Quel est le type d’une liste en Maple ?
Quelques commandes sur les listes et les suites
Les commandes présentées ici sont fondamentales. Si vous ne devez retenir qu’une
chose de ce TD, voire de l’année, retenez ce qui suit.
Conversion On peut transformer une suite en liste simplement en l’entourant de crochets :
> suite := 1,a,b;
suite := 1, a, b
> liste := [suite]; whattype (liste);
liste := [1, a, b]
list
On utilise la fonction op pour transformer une liste en suite.
> suite2 := op(liste);
suite2 := 1, a, b
Création Pour créer une suite, on se sert de la commmande seq(...). La syntaxe générale
est : seq( f(i), i=debut..fin)
> seq ( k^2 , k=5..20 ); # la suite des carrés de 5 à 20
25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400
Accès L’accès au i-ème élément d’une liste se fait avec la notation liste[indice] :
> liste := [37,78,25];
liste := [37, 78, 25]
> liste[1]; liste[3];
37
25
> liste[-1]; # le dernier terme de la liste (-2 pour l’avant dernier, etc...)
25
Cette notation s’emploie aussi pour extraire des sous-listes
> liste[2..3]; # la sous-liste composée des termes 2 à 3.
[78, 25]
Ajout d’un élément On peut également construire une liste en ajoutant des éléments
un par un. On le fait de la manière suivante :
> liste := [3,5,7,11];
liste := [3, 5, 7, 11];
> liste := [op(liste),13];
liste := [3, 5, 7, 11, 13];
[email protected]
2
pauldcsimon.net
TD 2
Structures de données
Des choses plus exotiques On utilise nops pour obtenir le nombre d’éléments dans une
liste ou une suite. On peut bien entendu faire des listes de listes, concaténer deux suites
(attention pour les listes, il faut utliser op). On utilise sort pour trier une liste.
D’autres structures de données
Maple permet d’utiliser des structures de données plus évoluées, mais qui servent des
besoins plus spécifiques. Parmi les plus importantes, on trouve les ensembles (correspondant aux ensembles mathématiques) et les tableaux (qui étendent la structure des listes de
façon plus robuste).
Un mot sur les ensembles Un ensemble (set en Maple) est une suite entourée d’accolades { et } qui se comporte comme un ensemble mathématiquement (pas d’ordre ni de
doublons).
Les opérations utiles sur les ensembles sont union, intersect, minus, nops et select.
Bases de programmation
Maple offre un environnement sommaire de programmation : les procédures. Une procédure est un groupe d’instructions qui sont placées dans la même commande Maple. La
syntaxe pour les créer est la suivante :
>nom := proc (argument_1,...,argument_n)
local var_1,...,var_i;
global var’_1,...,var’_j;
instruction_1;
...
instruction_p;
end;
Ces procédures généralisent en quelque sorte la notion de fonction : ce sont des boîtes
noires qui prennent des arguments en entrée et renvoient un résultat. Elles permettent cependant de réaliser des calculs plus compliqués (utilisation de boucles, de variables intermédiaires).
Les points importants à retenir sont la présence du proc au début et du end à la fin,
ainsi que les deux façons de déclarer ses variables. On utilisera Maj+Entrée pour sauter
des lignes sans envoyer la procédure incomplète à Maple.
Par défaut, le résultat d’une procédure est la dernière chose calculée avant le end. On
peut également faire renvoyer le résultat de façon explicite avec un RETURN(...).
Structure conditionnelle : le if
Les branchements conditionnels du type "Si telle condition est vraie alors fais telle chose
et sinon fais telle autre chose" s’écrivent en Maple avec la syntaxe if ... then ... else ...
fi :
if condition then instruction;
elif autre_condition then autre_instruction;
elif ...;
else derniere_instruction;
fi;
Bien sûr, remplacez "condition" par une vraie condition Maple.
Exercice 4
Écrire une procédure proc1:=proc(x) qui renvoie x/2 si x est pair et 3x + 1 sinon. On
utilise irem(n,k) pour connaitre le reste de la division euclidienne de n par k.
[email protected]
3
pauldcsimon.net
TD 2
Structures de données
>proc1:=proc(x)
if irem(x,2)=0 then x/2
else 3*x+1;
fi;
end;
Structures itératives : le while et le for
Les boucles itératives vous permettent de réaliser des opérations répétitives tant qu’ une
certaine condition n’est pas remplie (boucle while) ou pour toute valeur d’une valeur dans
un certain intervalle (boucle for)
Boucle for Sa syntaxe générale est :
>for variable from début to fin by pas do
instruction;
...;
od;
Maple exécutera les instructions entre le do et le od pour chaque valeur de la variable
du for entre les bornes de début et de fin, par saut de pas (par défaut cette valeur vaut 1).
Exercice 5
Écrire une procédure proc2:=proc(n) qui affiche tous les entiers pairs entre 0 et n. On
utilisera une boucle for et print(k) pour afficher l’entier k.
>proc2:=proc(n)
local i;
for i from 0 to n by 2 do
print(i);
od;
end;
Boucle while On l’écrit de la façon suivante :
>while condition do
instruction;
...;
od;
Les instructions comprises entre le do et le od seront effectuées en boucle tant que la
condition du while sera vérifiée.
Exercice 6 (Équivalence des boucles for et while)
Refaire l’exercice précédent en remplaçant la boucle for par une boucle while.
proc3:=proc(n)
local i;
i:=0;
while i<n do
print(i);
i:=i+2;
od;
end;
[email protected]
4
pauldcsimon.net
TD 2
Structures de données
Exercices
Exercice 7 (Rappels)
1. Définir sous forme d’une fonction f le polynôme x3 + 4 ∗ x − x + 5.
2. Calculer la valeur de f en 1 et en 7. Développer et simplifier f(a+b).
3. Dériver les expressions (commande diff) ln(x) + e5∗x , g(x) = sin(x) − cos(x) +
tan(x)
4. Trouver la dérivée troisième de g(x).
5. Soit f (x, y) =
x3 y 2
x4 +y 2 +1 .
Calculer les dérivées partielles de f.
6. Déterminer un développement limité à l’ordre 4 en 0 de cos(exp(x))
7. Calculer une primitive de f (x)cos(x) (f comme à la question 1)
8. Calculer l’intégrale entre 1 et 2 de cette même fonction.
Exercice 8
1. Construire la liste (ordonnée) des 200 premiers nombres premiers (la fonction
ithprime(i) renvoie le i-ème nombre premier).
2. Diviser tous ces nombres par 17 et appliquer la fonction frac(...) pour ne garder
que la partie fractionnaire des nombres (utiliser l’opérateur seq).
3. Multiplier ces éléments par 17 et construire une nouvelle liste composée du résultat.
4. Convertir cette liste en un ensemble et en donner le nombre d’éléments.
>l:=[seq(frac((ithprime(i))/17)*17,i=1..200)];
>s:={op(l)};
>nops(s);
Exercice 9
Refaire rapidement les deux premières questions de l’exercice précédent en utilisant des
procédures et des boucles for à la place des opérateurs seq.
>proc4:=proc()
local l,i;
l:=[];
for i from 1 to 200 do
l:=[op(l),ithprime(i)];
od;
for i from 1 to 200 do
l[i]:=l[i]/17;
od;
l;
end;
Exercice 10
1. Sans utiliser ithprime, écrire une procédure n_prem := proc(n) rendant la liste
des n premiers nombres premiers. On utilisera cependant isprime(n), qui renvoie
true si n est premier, false sinon.
2. En utilisant la procédure ci dessus, écrire une procédure double_somme := proc(n)
rendant la liste des sommes des paires des n premiers nombres premiers.
3. En utilisant la procédure ci-dessus, montrer que tous les nombres pairs entre 1 et
[email protected]
5
pauldcsimon.net
TD 2
Structures de données
1000 s’écrivent sous la forme d’une somme de deux entiers premiers.
Ce problème est connu sous le nom de “conjecture de Goldbach” : tout nombre pair
strictement supérieur à 2 peut-il s’écrire comme somme de deux nombres premiers ?
4. Bonus : Démontrer la conjecture de Goldbach.
>n_prem:=proc(n)
local i, k, l;
l:=[];
k:=0;
i:=2;
while k<n do
if isprime(i) then l:=[op(l),i];
fi;
k:=k+1;
od;
l;
end;
>double_somme:=proc(n)
local l1,l2,i;
l1:=n_prem(n);
l2:=[];
for i from 1 to n do
for j from 1 to n do
l2:=[op(l2),l1[i]+l1[j]];
od;
od;
l2;
end;
>l:=double_somme(200);
>s1:={l};
>s2{seq(2*i,i=1..500)};
>s2 minus s1;
Exercice 11
1. Créer une liste L2 constitué des carrés compris entre 1000 et 10000.
2. Créer une liste L3 constitué des cubes compris entre 1000 et 10000.
3. Combien y-a-t’il d’éléments en commun dans les deux listes L2 et L3. Combien
y-a-t’il d’éléments dans les deux listes réunies ?
4. Répéter la même chose avec L3 et L4 où L4 est constitué des puissances 4ièmes.
>L2:=seq(i*i,i=32..100);
>L3:=seq(i**3,i=10..21);
>nops({L2} intersect {L3});
>nops({L2} union {L3});
[email protected]
6
pauldcsimon.net
TD 2
Structures de données
Exercice 12
En utilisant les fonctions irem et iquo (respectivement le reste et le quotient de la division euclidienne), écrire un programme rendant une suite représentant la décomposition
d’un entier n > 0 en base b.
>decomp:=proc(n,b)
local q,r;
q,r:=iquo(n,b),irem(n,b);
if q=0 then [r]
else [op(decomp(q,b)),r];
fi;
end;
Exercice 13
– Écrire un programme qui rend une liste représentant la décomposition d’un entier
n en facteurs premiers.
– Écrire un programme prenant en entrée la décomposition d’un entier en facteur
premier et rendant l’entier en question.
– Vérifier que ces deux programmes sont bien l’inverse l’un de l’autre.
[email protected]
7
pauldcsimon.net