Vous êtes sur la page 1sur 28

144 Chapitre V

Énoncés des exercices

Exercices résolus

1
Indiquer la sortie écran du programme suivant:

class Program {
public static void Method1(string s, int n) {
Console.WriteLine("Method1 Start: n={0} and s={1}", n, s);
n++;
s = s + n;
Console.WriteLine("Method1 End: n={0} and s={1}", n, s);
}
public static void Method2(out int a, ref string str) {
a = 1;
Method1(str, a);
Console.WriteLine("Method2: After Method1: a={0} and str={1}", a, str);
a++;
str += a;
Console.WriteLine("Method2 End: a={0} and str={1}", a, str);
}
static void Main()
{
string ms = "hi";
int x;
Method2(out x, ref ms);
Console.WriteLine("Main: After Method2: x={0} and ms={1}", x, ms);
Console.ReadLine();
}
}
2
Trouver la sortie du programme suivant :

static int f(ref int p, int q) {


p = q++;
return(p);
}
static void g(int t) {
int n = 1;
n += 2*t;
t = 3*(n++);
}
static void Main() {
int a=1, b=3, n=2;

a += f(ref n, b);
Énoncés des exercices 145

Console.WriteLine("Etape 1: {0}\t{1}\t{2}", a, b, n);


b += f(ref a, n);
Console.WriteLine("Etape 2: {0}\t{1}\t{2}", a, b, n);
g(a);
Console.WriteLine("Etape 3: {0}\t{1}\t{2}", a, b, n);
g(b);
Console.WriteLine("Etape 4: {0}\t{1}\t{2}", a, b, n);
Console.ReadLine();
}
3
Qu’affiche ce programme?

static void Somme(ref int y,ref int z, int s) {


s = y++ + z++;
}
static void Main() {
int a=5, b=4, c=0;
Somme(ref a, ref b, c);
Console.WriteLine("a={0}\tb={1}\tc={2}\n", a, b, c);
}
4
Trouver la sortie du programme suivant:

static int f(int p) {


int a = 2;

if (p % a ==0) return(p/2);
else return((p+1)/2);
}
static void g(int u) {
Console.WriteLine("Mon suivant est {0}", u+1);
}
static void Main() {
int n=18;

n = f(n);
n = f(n);
g(n);
Console.WriteLine("Ma valeur est {0}", n);
Console.ReadLine();
}
5
Ecrire une méthode MinTab() qui prend en paramètres un tableau de réels et sa taille et retourne la valeur
minimale du tableau en valeur de retour de la méthode et l'indice du premier minimum en troisième
paramètre.
6
Ecrire une méthode MaxTab() qui prend en paramètres un tableau de réels et sa taille et retourne la valeur
maximale du tableau en valeur de retour de la méthode et l'indice du premier maximum en troisième
paramètre.
7
Ecrire une méthode int MinMaxTab() qui prend en paramètres un tableau de réels et sa taille et retourne
l'indice du premier minimum en valeur de retour, et l'indice du premier maximum dans le troisième
paramètre.
8
Ecrire une méthode MoyTab() qui prend en paramètres un tableau de réels et sa taille et retourne la
moyenne des valeurs du tableau.
9
Ecrire une méthode TriSelectMax(..., ...) qui prend en paramètre un tableau t de nombres réels (float) et sa
taille, et classe les éléments de t par ordre décroissant. Implémenter l'algorithme suivant:
146 Chapitre V

Méthode par sélection du maximum: parcourir le tableau t de gauche à droite à l'aide d'un indice i. Pour
chaque élément t[i], déterminer la position pmax du (premier) maximum à droite de t[i] et échanger t[i]
et t[pmax].
10
Ecrire une méthode StrInvertCase(...) qui prend une chaîne de caractères s en paramètre et convertit dans
la chaîne même ses lettres minuscules en majuscules, et vice-versa. Les caractères autres que les lettres
doivent rester inchangés.
11
Ecrire une méthode Str2InvertCase (..., ...) qui prend deux chaînes de caractères s1 et s2 en paramètres et
convertit les lettres minuscules de s1 en majuscules, et vice-versa. Les caractères de s1 autres que les
lettres doivent rester inchangés. La chaîne modifiée doit être stockée dans s2 et la chaîne s1 doit rester
inchangée.
12
Ecrire une méthode récursive calculant la valeur de la fonction d'"Ackerman" A(m, n) définie pour les
deux entiers strictement positifs m et n par:

 A(m  1, A(m, n  1)) pour m  0 et n  0



A(m, n)  n  1 pour m  0 et n  0
 A(m - 1,1 pour m  0 et n  0

13
Un palindrome est une chaîne de caractères qui se lit de même dans les deux sens (de gauche à droite et
de droite à gauche). Par exemple, "ABCBA", "i am ma i", "C" et "" (chaîne vide) sont des palindromes.
Ecrire une méthode récursive qui prend une chaîne de caractère en paramètre et retourne true si la chaîne
est un palindrome et false sinon. On n'a le droit d'utiliser que la propriété Length et l'on n'a pas le droit
d'utiliser des chaînes auxiliaires.
14
Ecrire une méthode Filtrer(dest, src, except) qui copie dans dest tous les caractères de src non présents
dans except.
15
Surcharger la méthode Filtrer() de façon à ce que le filtrage se fasse dans la chaîne src même. La
nouvelle méthode n'admet donc plus que deux paramètres.
16
Ecrire une méthode Tautogram() qui prend en paramètre une chaîne de caractères et retourne true si cette
chaîne est un tautogramme et false sinon. Un tautogramme est une chaîne dont tous les mots
commencent par la même lettre comme par exemple "Le lion lape le lait lentement", sans distinction
entre majuscules et minuscules.
17
On suppose que les seules opérations arithmétiques disponibles sont les méthodes plus_un(a) et
moins_un(a) qui prennent en paramètre un entier non signé et retournent respectivement la valeur de ce
paramètre incrémentée de 1 et décrémentée de 1. En d'autres termes, en écrivant les méthodes demandées
ci-après, le programmeur n'a pas le droit d'utiliser les caractères +, -, *, /.
a) Ecrire une méthode récursive Plus() qui prend en paramètres deux valeurs entières non signées et
retourne leur somme.
b) Utiliser les méthodes Plus() et moins_un() pour écrire une méthode récursive Mult()qui prend en
paramètres deux valeurs entières non signées et retourne leur produit.
18
Ecrire une méthode récursive DivEnt() qui prend en paramètres deux valeurs entières non signées et
retourne le quotient la division de la première par la seconde (on n'a bien sûr pas le droit d'utiliser
l'opérateur de division /).
19
Ecrire une méthode Equilibre() qui prend une chaîne de caractères en paramètre, l'interprète comme une
expression arithmétique et retourne true si les parenthèses y sont bien équilibrées et false sinon. La
méthode ne doit pas s'occuper de la validité mathématique de l'expression, mais uniquement vérifier si
toute parenthèse fermante correspond à une parenthèse ouvrante, et que toutes les parenthèses ouvrantes
Énoncés des exercices 147

sont fermées. Ainsi, l'expression "a+(c-d)(a-)" sera considérée comme correcte même si la sous-
expression (a-) n'a pas de sens; par contre, l'expression "(a-b))+d(" sera considérée comme erronée car la
seconde parenthèse fermante ne correspond pas à une parenthèse ouvrante, et pourtant le nombre de
parenthèses ouvrantes est égal à celui des parenthèses fermantes.
20
On considère qu'un polynôme est représenté par un tableau de ses coefficients réels (en double précision)
des termes de puissances 0 à DEGMAX, où DEGMAX+1 est la taille du tableau (propriété Length). Les
termes qui n'existent pas admettent des coefficients nul.
Ecrire les méthodes C# suivantes (toute méthode peut faire appel aux autres méthodes):

a) void Lirepolynome(): saisit au clavier un polynôme. Le polynôme lu est passé en paramètre p.


L'utilisateur (celui qui entre les coefficients) ne doit pas entrer les coefficients nuls du polynôme.
b) int degre(): retourne le degré du polynôme passé en paramètre.
c) void somme(p, q, s): calcule la somme des deux premiers polynômes passés en paramètre et place le
résultat dans le troisième paramètre.
d) double Valeur(p, x): retourne la valeur du polynôme p en x.
e) void Derivee(p, dp): place la dérivée de p dans dp.
f) int Integrale(p, ip, x0, v): place dans ip le polynôme intégrale de p prenant la valeur v au point x0. Si le
degré de p est égal à DEGMAX, l'opération ne peut se faire et la méthode retourne false, sinon, la
méthode retourne true.
21
Un point col d'une matrice réelle (double) est un élément de la matrice qui est maximum sur sa ligne et
minimum sur sa colonne ou minimum sur sa ligne et maximum sur sa colonne. Par exemple, dans la
matrice:
 2.5 10.6 8.1 1.3 
 4.2 13.7 1.9 3.1 
 ,
 9.0 15.8 11.4 12.3
 
 6.6 14.1 2.6 3.9 
l'élément 10.6 est un point col puisqu'il est maximum sur la première ligne et minimum sur la deuxième
colonne, et l'élément 9.0 est un point col car il est minimum sur la troisième ligne et maximum sur la
première colonne.
a) Ecrire une méthode void LireMatrice() qui permet de lire une matrice au clavier et de la stocker dans
son paramètre.
b) Ecrire une méthode void MaxMinLigne(T, lig, icolmin, icolmax) permettant de trouver les indices de
colonnes du minimum et du maximum de la ligne lig de la matrice T et de les stocker dans ses deux
derniers paramètres. On suppose que dans une même ligne, il y a un seul minimum et un seul
maximum.
c) Ecrire une méthode void MaxMinColonne(mat, col, iligmin, iligmax) permettant de trouver les indices
de lignes du minimum et du maximum de la colonne col de la matrice mat et de les stocker dans ses
deux derniers paramètres. On suppose que dans une même colonne, il y a un seul minimum et un seul
maximum.
d) Ecrire une méthode Main() qui permet de lire au clavier une matrice t (44) et d'afficher les indices et
les valeurs de ses points cols.
22
i
Un nombre complexe s'écrit en mode cartésien sous la forme z=x+iy et en mode polaire z  e
(=module, =angle ou phase).

On définit alors la structure Complexe suivante:

struct Complexe {
bool cartesien; // true si mode cartésien, false si polaire
double x, y;
}

Ecrire les méthodes suivantes:


148 Chapitre V

a) LireComplexe(): retourne un nombre complexe lu au clavier On demandera à l'utilisateur de préciser


le mode de représentation, et en fonction de son choix, on demandera les informations adéquates.
b) RendreCartesien(): rend cartésien (s'il ne l'est pas déjà) le mode de représentation du nombre
complexe pris en paramètre.
c) RendreCartesien(): surcharge de la méthode précédente pour que le nombre passé en paramètre reste
inchangé et le nombre converti soit retourné par la méthode.
d) RendrePolaire(): rend polaire (s'il ne l'est pas déjà) le mode de représentation du nombre complexe
pris en paramètre.
e) RendrePolaire():surcharge de la méthode précédente pour que le nombre passé en paramètre reste
inchangé et le nombre converti soit retourné par la méthode.
f) ChangerMode(): change le mode de représentation du complexe pris en paramètre.
g) Somme(): retourne la somme de tous les nombres complexes donnés en liste de paramètres. On tiendra
compte du fait que ces nombres peuvent être représentés dans des modes différents. Le mode du
complexe retourné est précisé dans le premier paramètre.
h) Produit(): retourne le produit de tous les nombres complexes donnés en liste de paramètres. On
tiendra compte du fait que ces nombres peuvent être représentés dans des modes différents. Le mode
du complexe retourné est précisé dans le premier paramètre..
i) Afficher(): affiche à l'écran le nombre complexe donné en paramètre suivant son mode.
j) Distance(): retourne la distance entre les deux complexes donnés en paramètre.
k) PlusProcheVoisin(): prend en paramètre un tableau tc de complexes, sa taille s, et un complexe z et
retourne l'indice dans le tableau tc du complexe le plus proche de z (au sens de la distance entre deux
points). Si la taille s est nulle, la méthode retourne -1.
l) Main(): lit au clavier une suite de nombres complexes (dans des modes choisis par l'utilisateur pour
chaque complexe) et affiche leur somme et leur produit dans le mode voulu par l'utilisateur, puis lit un
autre nombre complexe z0 et affiche le nombre complexe de la suite précédente qui est le plus proche
de z0.
23
Ecrire une méthode ArrangerImpairPair() qui prend deux paramètres: un tableau d'entiers et sa taille, et
arrange les éléments de ce tableau de façon à ce qu'il se présente comme suit:
…nombres impairs…. …nombres pairs….
24
Ecrire une méthode TriImpairPair() qui prend deux paramètres: un tableau d'entiers et sa taille, et
effectue le tri des éléments du tableau de façon à ce qu'il se présente comme suit:

nombres impairs triés nombres pairs triés par


par ordre croissant ordre croissant
25
Ecrire une méthode EndMin() prenant en paramètre deux chaînes de caractères et retournant 0, 1 ou 2
suivant que le dernier caractère de la première chaîne est égal, inférieur ou supérieur au dernier caractère
de la seconde chaîne. Par exemple:
EndMin("quatre", "cinq") = 1
EndMin("quatre", "arriere") = 0
EndMin("drink", "switch") = 2.
26
La méthode de Newton permet de résoudre une équation de type f(x) = 0. Le principe de la méthode
consiste à construire une suite x0, x1, ..., xn, ... qui converge lorsque certaines conditions sont vérifiées vers
une solution de l'équation f(x)=0. Cette suite est définie à partir d'un point de départ quelconque x0 et la
relation de récurrence:
f ( xn )
x n 1  x n  .
f ( x n )
Ecrire une méthode Racine(a, x0, e, r) calculant la racine carrée positive r du réel positif a en utilisant le
fait que cette racine est solution de l'équation f(x)=x2-a. Le point de départ est x0. On supposera que la
Énoncés des exercices 149

convergence est atteinte lorsque l'écart relatif entre deux termes successifs de la suite xn est inférieur en
valeur absolue à e. Tous les nombres réels manipulés sont en double précision.
27
Ecrire une méthode CompareDate() qui prend deux paramètres représentant des chaînes de caractères
décrivant deux dates et chacune sous la forme "jj/mm/aaaa", et qui retourne 0 si les deux dates sont les
mêmes, 1 si la première est antérieure à la seconde et 2 sinon. Le séparateur / peut être remplacé par un
des séparateurs suivants: - (moins), . (point) ou : (deux-points). Les champs jj, mm peuvent être de
longueur variable. La méthode retourne -1 si une des dates comporte une erreur (manque de séparateur,
…etc.).
28
Un entier positif est dit un nombre d'Armstrong s’il est égal à la somme des cubes de ses chiffres (comme
le nombre 153=13+53+33).

a) Ecrire une méthode GetDigit(ulong n, uint r) retournant le chiffre (int) de rang r (à partir de la droite)
de l’entier positif n et –1 si ce rang est trop grand. Par exemple:
GetDigit(35870, 1)= 0 GetDigit (35874, 2)= 7
GetDigit (35870, 4)= 5 GetDigit (35874, 6)= -1.
b) Ecrire une méthode IsArmstrong() qui retourne true si l’entier positif passé en paramètre est un
nombre d’Armstrong et false sinon.
c) Ecrire une méthode AfficheArmstrongJusque() qui affiche à l’écran tous les nombres d'Armstrong
inférieurs à une limite passée en paramètre.
d) Ecrire une méthode AffichePremiersArmstrongJusque(nb, m) qui prend en paramètre deux entiers nb
et limite et affiche à l'écran les nb premiers nombres d'Armstrong inférieurs ou égaux à limite.
29
La médiane d'une suite de n nombre réels (xi) est la valeur M définie par :

 y [ n / 2 ] 1 si n est impair

M   y n / 2  y n / 21 (les crochets représentent la partie entière).
 si n est pair
2
(attention aux indices en C# par rapport à cette formule mathématique!),
où y est le tableau des n nombres xi rangés par ordre croissant.

a) Ecrire une méthode Mediane(x, n) qui retourne la médiane des n réels se trouvant dans le tableau x
(ces réels sont dans un ordre quelconque et doivent le rester après le retour de la méthode). Par
exemple, Mediane([1.4, 1.2, -1.6, 1.5, 1.8, 1.1, 0.9], 7)=1.2.
b) Ecrire une méthode Taux(x, n, nbgroupes, tgroupemax) ayant 4 paramètres dont le premier est un
tableau de n réels. Cette méthode doit affecter à chacun de ces réels le signe "+" s’il est supérieur à la
médiane M de tous les nombres de x, le signe "-" s’il est inférieur à M, et aucun signe s’il est égal à la
médiane. La méthode doit ensuite affecter à son troisième paramètre le nombre de groupes de signes,
et à son dernier paramètre la taille du plus grand groupe de signes. Par exemple:
taux([1.4, 1.2, -1.6, 1.5, 1.8, 1.1, 0.9], 7, …, …)
doit calculer la médiane M = 1.2 et affecter les signes comme suit :
1.4 1.2 -1.6 1.5 1.8 1.1 0.9
+ - + + - -
pour ensuite affecter la valeur 4 (groupes de signes) à son troisième paramètre et la valeur 2 (taille du
plus grand groupe de signes) à son dernier paramètre.
30
Considérons le système carré triangulaire inférieur A.x = b:
150 Chapitre V

 0 0 0 0 0 0   
     
.  0 0 0 0 0  .  . 
. .  0 0 0 0  .  . 
     
. . .  0 0 0   .   . 
. . . .  0 0   .   . 

. . . . .  0  .  . 
     
 . . . . .   .  . 
où A est une matrice carrée de réels (double), x et b sont des vecteurs de réels (double).
a) Ecrire une méthode appelée ResoudreTriangInf() qui accepte admet les 3 paramètres A, b, x et place
dans le vecteur x (déjà alloué) la solution du système triangulaire A.x =b.
b) Ecrire une méthode LireSysteme() qui prend 2 paramètres: A et b et qui saisit A et b (déjà alloués) à
partir du clavier. On ne doit lire que la partie inférieure (non nulle) de A.
c) Ecrire la méthode Main() permettant de lire au clavier la taille du système, allouer pour les tableaux,
appeler les deux méthodes précédentes et afficher la solution du système A.x =b.
31
Sachant qu’une matrice carrée A de réels (double) est triangulaire inférieure (éléments au-dessus de la
première diagonale tous nuls), on économise de la place mémoire en stockant cette matrice dans un
vecteur (tableau à une seule dimension) en y plaçant ligne par ligne uniquement les valeurs en dessous ou
sur la diagonale.
Ecrire une méthode Element(m, lig, col) qui retourne l'élément d'indices lig et col de la matrice
triangulaire inférieure stockée en tant que vecteur dans m . Les indices lig et col commencent à 0.
32
Ecrire une méthode DiffTab(t1, taille1, t2, taille2, t3, taille3) qui place dans le tableau t3 la différence des
tableaux d'entiers t1 et t2 de tailles respectives taille1 et taille2, c'est-à-dire que t3 doit contenir les
éléments de t1 qui ne sont pas dans t2. La méthode doit placer la taille du tableau t3 dans le dernier
paramètre. Les tableaux sont tous alloués.
33
Ecrire une méthode Combiner() qui prend deux paramètres A et B de type ushort (entier non signé sur 16
bits) et retourne un entier de type ushort formé de la façon suivante (on note AL et AH les octets de poids
faible et de poids fort de A, BL et BH les octets de poids faible et de poids fort de B, et S la somme des
valeurs des bits de AH):
4 bits 4 bits 4 bits 4 bits

2*S-1 si S0 Les 4 bits de Complément à Les 4 bits de


0 si S=0 poids faible de 1 bit-à-bit des poids faible de
BH 4 bits de poids AL dans l'ordre
fort de BL inverse.
34
Ecrire une méthode UlToX(x, uporlow, s) qui permet de coder en hexadécimal dans la chaîne s l'entier
long positif x. Les lettres utilisées pour le codage de 10,.., 15 seront 'A'...'F' si uporlow est une lettre
majuscule et 'a'...'f' sinon.
35
Ecrire une méthode récursive Scalaire() acceptant deux tableaux de réels (float) et leur taille (commune)
en paramètres et retournant leur produit scalaire.
36
Ecrire une méthode MinImpairs() qui accepte un tableau d'entiers et sa taille et retourne la plus petite
valeur impaire du tableau. Si le tableau ne contient aucune valeur impaire, la méthode doit retourner 0.
37
Ecrire une méthode Inclus() qui prend quatre paramètres qui sont deux tableaux d'entiers et leurs tailles
respectives, et retourne true si le premier tableau est inclus dans le second, c'est-à-dire que chaque
élément du premier tableau figure au moins une fois dans le second tableau. Sinon, la méthode retourne
false.
Énoncés des exercices 151

38
Ecrire une méthode FusionTab() qui prend cinq paramètres. Les quatre premiers sont deux tableaux
d'entiers et leurs tailles respectives. Chacun de ces deux tableaux est trié par ordre croissant des éléments.
La méthode doit effectuer la fusion de ces deux tableaux dans un seul autre tableau (le cinquième
paramètre supposé alloué) de façon à ce que ce dernier soit aussi trié par ordre croissant de ses éléments.
39
Ecrire une méthode récursive Inverser(s, i, j) qui inverse dans la chaîne s l'ordre des caractères de l'indice
i à l'indice j.
40
Ecrire une méthode récursive Cpn(n, p) calculant le nombre C p (pn) en utilisant les propriétés des
n

n 1
combinaisons, à savoir: C p  C p
n
 C pn11 C 0n  1 C nn  1 .
41
Ecrire une méthode récursive BinarySearch(t, debut, fin, x) qui retourne l'indice de la valeur x dans le
tableau d'entiers t dont les éléments sont rangés par ordre croissant. La recherche doit se limiter à la
portion du tableau allant de l'indice debut à l'indice fin. Si la valeur x n'est pas dans t, la méthode retourne
-1. La recherche de x dans t doit se faire en appliquant la méthode dite par dichotomie (ou binaire): si la
taille du tableau est 1 (deb=fin), alors on compare x à l'élément du tableau et on retourne la valeur suivant
le résultat du test. Si la taille du tableau est supérieure à 1, alors on recommence la recherche dans la
première moitié du tableau si x est inférieure à la valeur du milieu, et dans la seconde moitié sinon.
42
Ecrire une méthode Placer() qui prend en paramètre un tableau t d'entiers et sa taille, ainsi qu'un indice i,
et place l'élément t[i] dans sa place dans le tableau comme s'il était trié par ordre croissant des valeurs.
43
Ecrire une méthode PurgerTabTab() qui prend en paramètre deux tableaux d'entiers et leurs tailles
respectives et supprime dans le second tableau la première occurrence de la séquence des valeurs
contiguës formée de tous les éléments du premier tableau. Par exemple, si le tableau t2 contient les
valeurs {1,2,3,4,5,6,7,8,9,3,4,5,6,10}, et si le tableau t1 contient les valeurs {3,4,5}, alors le contenu du
tableau t2 devient {1,2,6,7,8,9,3,4,5,6,10}. La méthode retourne true si la séquence est trouvée et
supprimée, et false sinon.
44
Ecrire une méthode DecomposerEntier(i, signe, nchiffres, chiffres) qui décompose l'entier i en signe: 1 si
i<0, 0 si i0, nchiffres: le nombre de chiffres de i (nchiffres=0 si i=0), chiffres: tableau non alloué
d'entiers formant les chiffres de i.
45
Ecrire une méthode récursive double Puissance(double x, int n) qui retourne xn. On rappelle que:
x0 =1
1
x k  si k > 0
xk
xk = x si k=1
xk = x.xk-1 si k>0 et k impair
k
xk = ( x 2
)2 si k>0 et k pair.
46
Afin de fabriquer un distributeur automatique de billets, on demande d'écrire une méthode
payer(disponible, somme, billets) qui décompose la somme (entier positif) à payer en un tableau de billets
(déjà alloué) formé du nombre de billets de 10000, 20000, 50000, 100000 dont les quantités disponibles
dans le distributeur sont contenues dans les cases respectives du tableau disponible: la case disponible[0]
contient le nombre de billets de 10000 disponibles, ..., la case disponible[3] contient le nombre de billets
de 100000 disponibles. Lorsque l'opération est possible, la méthode doit mettre à jour le tableau
disponible (en décrémentant les nombres de billets) , remplir le tableau billets du nombre de billets à
rendre dans chaque catégorie et retourner true. Si l'opération est impossible, la méthode retourne false.
La stratégie à prendre est bien sûr de donner autant de "gros" billets que possible. Par exemple:

Avant appel: disponible = {50, 28, 17, 12}, somme=680000


Après appel: disponible = {49, 27, 16, 6}, billets = {1, 1, 1, 6} et retour = true.
152 Chapitre V

Avant appel: disponible = {50, 0, 17, 12}, somme=680000


Après appel: disponible = {47, 0, 16, 6}, billets = {3, 0, 1, 6} et retour = true.

Avant appel: disponible = {3, 2, 0, 12}, somme=680000


Après appel: disponible = {3, 2, 0, 12}, et retour = false (opération impossible).
47
Ecrire une méthode récursive PrintX() qui affiche à l'écran la représentation hexadécimale de l'entier
positif n.
48
Ecrire une méthode TriBulle() qui prend en paramètre un tableau de réels (double) et sa taille et effectue
le tri de ses éléments par ordre croissant en implémentant l'algorithme de tri bulle suivant: on compare le
premier nombre et le second et on les permute s'ils ne sont pas dans le bon ordre, on recommence en
prenant le second et le troisième et ainsi de suite jusqu'au dernier. Ceci définit une étape de l'algorithme.
On recommence cette étape autant de fois que nécessaire jusqu'au moment où aucune permutation ne se
produit au cours d'une étape. Le tableau est alors trié. En voici un exemple d'application:

Etape 1 Etape 2 Etape 3 Etape 4


10, 11, 8, 7, 12, 9 10, 8, 7, 11, 9, 12 8, 7, 10, 9, 11, 12 7, 8, 9, 10, 11, 12
10, 11, 8, 7, 12, 9 8, 10, 7, 11, 9, 12 7, 8, 10, 9, 11, 12 7, 8, 9, 10, 11, 12
10, 8, 11, 7, 12, 9 8, 7, 10, 11, 9, 12 7, 8, 9, 10, 11, 12 7, 8, 9, 10, 11, 12
10, 8, 7, 11, 12, 9 8, 7, 10, 11, 9, 12 7, 8, 9, 10, 11, 12 7, 8, 9, 10, 11, 12
10, 8, 7, 11, 12, 9 8, 7, 10, 9, 11, 12 7, 8, 9, 10, 11, 12 7, 8, 9, 10, 11, 12
10, 8, 7, 11, 9, 12 8, 7, 10, 9, 11, 12 7, 8, 9, 10, 11, 12 7, 8, 9, 10, 11, 12
(Aucune permutation)
49
La distance de Hamming entre deux mots (string) de même longueur est égale au nombre de lettres, à la
même position, qui diffèrent. Par exemple la distance de Hamming entre “rose” et “ruse” est de 1, alors
que la distance de Hamming entre “110110” et “000101” est de 4.
a) Ecrire une méthode Hamming() qui prend en paramètre deux mots et retourne leur distance de
Hamming, ou -1 s’ils ne sont pas de même longueur.
b) Ecrire une version récursive HammingRec() de la méthode Hamming().
c) Un langage est un ensemble de mots. La distance de Hamming d’un langage est égale au minimum des
distances de Hamming entre les mots de ce langage pris deux à deux. Ecrire une méthode itérative
HammingLanguageIter() qui prend en paramètre un langage comme tableau de mots (tableau de
string), ainsi que le nombre de mots, et retourne la distance de Hamming de ce langage. Cette méthode
retourne -1 si deux mots de ce langage ne sont pas de même longueur.
d) Ecrire une version récursive HammingLanguageRec() de la méthode HammingLanguageIter().
50
Ecrire une méthode récursive Pgcd() retournant le p.g.c.d de ses deux paramètres entiers non signés
(ulong).
51
Les matrices de réels (double) manipulées dans cet exercice sont rectangulaires mais pas nécessairement
carrées. Ecrire les méthodes suivantes: (les allocations en mémoire sont supposées non faites pour les
matrices avant l'appel de ces méthodes)
a) Saisie(): saisie du nombre de lignes et de colonnes puis des composantes de la matrice passée en
paramètre.
b) Addition(): fait la somme des deux premières matrices passées en paramètre et place cette somme dans
le troisième paramètre. On vérifiera que le nombre de lignes de la première matrice est égal au nombre
de lignes de la deuxième, de même pour les colonnes. Cette méthode doit retourner true si l'opération
s'est bien passée et false sinon.
c) Multiplication (): fait le produit des deux premières matrices passées en paramètre et place ce produit
dans le troisième paramètre. On vérifiera que le nombre de lignes de la deuxième matrice est égal au
nombre de colonnes de la première. Cette méthode doit retourner true si l'opération s'est bien passée et
false sinon.
Énoncés des exercices 153

52
Comme nous l'avons dit au paragraphe 7.1.2 du chapitre III, la classe System.Console n'offre pas de
méthode pour lire au clavier une suite de valeurs données par l'utilisateur sur une seule ligne, comme par
exemple:

348 215 Dupont Jean 1246.50 14

En effet, la méthode Console.ReadLine() permet de lire au clavier une ligne entière et la méthode Parse()
permet de transformer en un type donné toute la ligne supposée contenir une seule valeur. Pour pouvoir
traiter plusieurs valeurs fournies sur une même ligne, le programmeur doit écrire ses propres méthodes.
On va supposer qu'on a lu la ligne tapée par l'utilisateur et que cette ligne est stockée dans une chaîne de
caractères (string). Il est demandé d'écrire les méthodes suivantes:
a) static bool IsSpace(char c): retourne true si c est un caractère d'espacement (' ', '\n', '\t', '\r', '\f') et
false sinon.
b) static long ReadLong(string s, int debut, out int fin): prend comme paramètres d'entrée une chaîne,
l'indice de début de l'entier dans la chaîne, et convertit en un entier long les caractères de cette chaîne
à partir de l'indice debut jusqu`à la fin de la chaîne ou jusqu'à la rencontre d'un caractère d'espacement
(' ', '\n', '\t', '\r', '\f'). La méthode doit d'abord sauter tous les caractères d'espacement jusqu'à la
rencontre du signe + ou - ou d'un chiffre. La méthode doit placer dans le paramètre de sortie fin
l'indice dans la chaîne s du caractère auquel la conversion s'est arrêtée. Elle retourne l'entier converti
de type long. On suppose que lorsque cette méthode est appelée, la chaîne donnée en paramètre ne
contient pas d'erreur. Voici des exemples d'appels et leurs résultats:
a = ReadLong(" 871 -4002 Dupont +126", 0, out f)  a = 871 f=6
b = ReadLong("871 -4002 Dupont +126", 3, out f)  b = -4002 f=9
c = ReadLong("871 -4002 Dupont +126", 16, out f)  c = 126 f = 21
c) static double ReadDouble(string s, int debut, out int fin): idem que la méthode précédente sauf qu'elle
doit lire un réel double qui peut contenir le point décimal ainsi que le caractère e (ou E) d'exposant 10.
Par exemple:
d = ReadDouble ("871 -13.79 Dupont +126", 3, out f)  d = -13.79 f = 10
e = ReadDouble ("Jaune 86.3E-15 Tripoli", 5, out f) e = 86.3E-15 f = 14
d) static string ReadString(string s, int debut, out int fin): idem sauf que la méthode doit extraire de s la
sous chaîne qui commence à l'indice debut. La sous chaîne extraite peut être entourée de deux doubles
quottes ("…") dont elle doit être privée dans la chaîne retournée. En absence de ces doubles quottes, la
conversion s'arrête au premier caractère d'espacement. Les espaces en début de la sous chaîne doivent
être supprimés mais pas ceux du milieu en cas de présence de doubles quottes. Par exemple:
m = ReadString ("871 -4002 Dupont +126", 9, out f)  m = Dupont f = 16
n= ReadString ("3 " Dupont Jean" +126", 1, out f) n=Dupont Jean f = 18
e) Une méthode Main() pour tester les méthodes écrite. Elle demande à l'utilisateur de donner sur une
même ligne l'age, le nom et le salaire d'une personne, place ces trois valeurs dans des variables de
types respectifs int, string et float et affiche le message suivant: La personne ……dont l'âge est
……touche …….$ par mois. Tester votre programme dans le cas où l'utilisateur fournit la ligne
suivante:
45 "Dupont Pierre" 1205.50
53
Il s'agit de résoudre le problème de lecture de plusieurs valeurs sur une même ligne beaucoup plus
simplement que la solution proposée dans l'exercice précédent. Rappelons que la méthode string.Split()
(cf. Annexe C, §3) permet de découper une chaîne de caractères en considérant une suite de séparateurs.
Ecrire une méthode Lire3() qui prend en paramètre un entier, un réel et un autre entier, et lit au clavier 3
valeurs et les stocke dans ces paramètres. L'utilisateur peut donner ces trois valeurs comme il le désire:
sur une même ligne ou sur plusieurs lignes, séparées par un ou plusieurs espaces et tabulations.
54
Lors d'une course de relais, une équipe est composée de 4 relayeurs. Le temps effectué par chaque
relayeur est exprimé sous forme d'une structure contenant le nombre de minutes, de secondes et de
centièmes de seconde (tous des uint). Par exemple, le temps {4, 28, 89} représente 4 minutes, 28
secondes et 89 centièmes de seconde.
a) Définir une structure Time.
154 Chapitre V

b) Définir une méthode AddTimes() prenant trois structures Time en paramètre et plaçant la somme des
deux premiers temps dans le troisième. Les simplifications doivent être faites (maximum 99
centièmes et maximum 59 secondes). On suppose que le temps total n'atteindra pas les 60 minutes.
c) Ecrire une méthode CompTimes() qui prend en paramètre deux structures Time et retourne la valeur -
1 si le temps représenté dans la première structure est inférieur à celui représenté dans la seconde, +1
s'il est supérieur et 0 s'ils sont égaux.
d) Ecrire une méthode Main() qui permet de:
 lire au clavier les temps des 4 relayeurs,
 Afficher la somme de leurs temps (minutes, secondes, centièmes de secondes),
 Afficher le meilleur et le moins bon temps (minutes, secondes, centièmes de secondes).
55
La traduction d'un mot en code Morse se fait en remplaçant chaque lettre (minuscule ou majuscule) de
l'alphabet par une suite de points (.) et de tirets (-) suivant le tableau ci-après:
a .- b -… c -.-. d -.. e . f ..-. g --. h …. i ..
j .--- k -.- l .-.. m -- n -. o --- p .--. q --.- r .-.
s … t - u ..- v …- w .-- x -..- y -.-- z --..

Afin de stocker ces codes, on suppose qu'on dispose du tableau de chaînes suivant:

string[] codes={".-", "-…", ………………………, "--.."};

Ainsi, le second code qui est "-…" correspondant à 'b' ou 'B' sera référencée par codes[1].
a) Ecrire une méthode Morse() prenant en paramètre deux chaînes de caractères et plaçant le code
morse de la seconde dans la première. On supposera que le mot ne contient que des lettres de
l'alphabet (minuscules ou majuscules).
b) Ecrire une méthode Main() qui prend en paramètre un mot et affiche à l'écran le mot codé
correspondant. Par exemple, si le fichier exécutable s'appelle morser.exe, et si l'utilisateur tape (sous
un Dos-Prompt) la commande: morser Grand
alors le programme doit afficher le code suivant:
--..-..--.-..
56
Un élément d'un tableau t de n entiers est dit prépondérant s'il apparaît dans t strictement plus de n/2
fois. Un tableau est dit prépondérant s'il contient un élément prépondérant (qui dans ce cas sera
forcément unique).
a) Ecrire une méthode Preponderant() qui prend en paramètre un tableau et sa taille et retourne l'indice
dans t de l'élément prépondérant s'il en existe, et -1 sinon.
b) Proposer une version récursive en ajoutant un 3ème paramètre

57
On considère l'algorithme suivant qui permet d'effectuer la multiplication Alexandrine de deux nombres
entiers positifs:
Soient x et y les deux entiers à multiplier;
 On place dans une première colonne les quotients des divisions entières successives de x par 2
jusqu'à obtenir 1
 On effectue autant de multiplications de y par 2 et on place les produits dans une seconde colonne
 On calcule la somme des éléments de la seconde colonne qui correspondent aux éléments impairs de
la première colonne; cette somme constitue le produit de x par y.

Exemple: x y
83 21
41 42
20 84
10 168
5 336
2 672
1 1344 x*y = 21+42+336+1344 = 1743
Énoncés des exercices 155

a) Ecrire une méthode AlexMult()() qui prend deux entiers positifs en paramètre et retourne leur produit
en appliquant l'algorithme précédent. Dans cette méthode, on ne doit jamais utiliser le symbole de
multiplication (*) ni de division (/ ).
b) Ecrire une version récursive de la méthode AlexMult()().
58
On dit qu’un entier positif de 5 chiffres possède la propriété d’être Bon5 si ses chiffres et ceux de son
double couvrent exactement (sans répétition) les dix chiffres de 0 à 9. Par exemple, les nombres suivants
possèdent la propriété Bon5 : 13485, 26907, 31485, 46851, 48531, 48651.
a) Ecrire une méthode Bon5() qui prend en paramètre un entier positif (uint) de 5 chiffres et retourne
true s’il possède la propriété Bon5 et false sinon.
b) Ecrire une méthode Main() qui permet d’afficher à l’écran tous les entiers positifs de 5 chiffres ayant
la propriété Bon5.
59
Ecrire une méthode Arsac() qui prend en paramètre un tableau d'entiers ainsi que sa taille et retourne la
longueur du plus grand plateau d'Arsac dans ce tableau (suite d'éléments consécutifs égaux). Par exemple,
Arsac( { 2,5,5,7,7,7,7,8,9,9,9,13 }, 12) retourne 4.
60
Ecrire une méthode récursive Persistance() qui retourne la persistance de son paramètre entier positif. La
persistance d'un entier est définie comme suit
Si ce nombre n'a qu'un chiffre, c'est 0.
Sinon, c'est le nombre de fois qu'il faut remplacer ce nombre par le produit de ses chiffres pour obtenir un
nombre d'un chiffre.
Exemple : la persistance de 1999 est égale à 4 car:
1 : 1 x 9 x 9 x 9 = 729
2 : 7 x 2 x 9 = 126
3 : 1 x 2 x 6 = 12
4 : 1 x 2 = 2 c'est un nombre formé d'un seul chiffre.
61
On suppose disponible une méthode int Hasard (int n) qui fournit aléatoirement un entier compris entre 0
et n-1. On utilise Hasard(2) pour simuler une marche aléatoire sur un axe: selon le résultat, on fait un pas
en avant (1) ou un pas en arrière (0) ; de même, on utilise Hasard(4) pour simuler une marche aléatoire
sur un quadrillage plan: selon le résultat, on fait un pas vers le Nord (0), ou vers l'Est (1), ou vers le Sud
(2), ou vers l'Ouest (3). Dans tous les cas, on part de l'origine, et on appelle retour à l'origine tout passage
par le point de départ après k pas (k > 0).
a) Ecrire une méthode Axe() à quatre paramètres qui simule une marche aléatoire de n pas sur un axe en
partant de l'origine (x=0); cette méthode devra calculer l'abscisse (a) du point d'arrivée, l'abscisse (d)
du point le plus à droite atteint au cours de la marche, et le nombre (r) de retours à l'origine.
b) Ecrire une méthode Quadrillage() à paramètre n, qui simule une marche aléatoire d'au plus n pas en
partant de l'origine (x=y=0) sur un quadrillage plan, jusqu'au premier retour à l'origine, et retourne le
nombre de pas effectués. Si on ne retourne pas à l'origine au bout de n pas, la méthode retourne 0.
62
On considère un polygone P tracé dans une fenêtre rectangulaire définie par une matrice d'entiers de n
lignes et m colonnes. Les points du bord (points noirs) du polygone sont placés à 1 et les autres points à
0. Soit M0 un point intérieur au polygone P et se trouvant sur la ligne n0 et la colonne m0.
156 Chapitre V

On se propose de remplir en noir l'intérieur du polygone avec l'algorithme récursif suivant: on noircit M0
et les points blancs voisins de M0 et les voisins blancs des voisins qui viennent d'être noircis. Les voisins
considérés sont les voisins immédiats dans les quatre directions Nord, Est, Sud et Ouest.

Ecrire une méthode récursive Remplir() qui prend en paramètre une matrice d’entiers mat, son nombre de
lignes n, son nombre de colonnes m, les coordonnées n0 et m0 d'un point intérieur M0, et effectue le
remplissage du polygone tracé dans la matrice.

63
Ecrire une méthode Develop() qui prend en paramètre un tableau contenant des entiers comme dans
l’exemple suivant :
2, 5, 4, 3, 1, -6, 3, 7, 4, 32
Chaque couple de valeurs constitue le nombre d’occurrences de l’entier suivi de l’entier lui-même.
La méthode doit prendre en paramètre un second tableau pour lequel elle doit allouer le nombre exact de
cases et y placer chacune de valeurs, autant de fois qu’elle est spécifiée. Pour l’exemple précédent, le
second tableau doit comporter les valeurs suivantes :
5, 5, 3, ,3, 3, 3, -6, 7, ,7 ,7, 32, 32, 32, 32
Le nombre de valeurs du premier tableau doit être pair. Si c’est le cas, la méthode effectue le traitement
demandé et retourne true, sinon elle retourne false sans rien faire.
Ecrire ensuite une méthode Main qui permet de tester la méthode précédente en lisant au clavier le
premier tableau, puis en faisant appel à la méthode et enfin en affichant les valeurs du second tableau.
64
Ecrire une méthode RightLeftBits() qui prend en paramètre un entier non signé (uint) a supposé sur 32
bits, et retourne un autre entier du même type obtenu en prenant successivement un bit de poids faible
suivi d’un bit de poids fort de n, et en les plaçant dans le nouvel entier de gauche vers la droite.
Par exemple, si a vaut en binaire :

1552638421 = 01011 1 0 0 1 000 1 0 1101 1 0 000 1 1 1 0 10101


alors l’entier retourné vaut :
2581250157 = 10011001110110101100000001101101
65
Le cryptage du Carré de Polybe consiste à remplir les 36 cases d’un carré 6x6 avec les 26 lettres de
l’alphabet de A à Z et les 10 chiffres de 0 à 9.

1 2 3 4 5 6
1 A B C D E F
2 G H I J K L
3 M N O P Q R
4 S T U V W X
5 Y Z 0 1 2 3
6 4 5 6 7 8 9

Chaque caractère du texte clair est ensuite remplacé par une paire de chiffres qui sont le numéro de ligne
et de colonne du caractère dans le carré. L’espace sera codé 00. Les caractères non présents dans le carré
seront ignorés (donc non codés et non présents dans le texte crypté). Ainsi, le caractère I sera codé 23, le
caractère X sera codé 46, et le chiffre 5 sera codé 62. La chaîne de caractères "C’est l’exemple 1" sera
codée : "131541420026154615313426150054".
a) Ecrire une méthode PolybeCharCode() qui prend en paramètre un carré de Polybe p supposé rempli,
un caractère c, et place dans son troisième (resp. quatrième) paramètre le numéro de ligne (resp. de
colonne) du caractère c dans le carré p et retourne true. Si le caractère c est un espace, elle place 0 et 0
dans ces paramètres et retourne true. Pour les autres caractères, elle place -1 et -1 et retourne false.
b) Ecrire une méthode PolybeStringCode() qui prend en paramètre un carré de Polybe p supposé rempli,
une chaînes de caractères clair, et retourne cette chaîne cryptée.
Énoncés des exercices 157

66
Partant de la chaîne de caractères "1", on souhaite obtenir et afficher une suite de mots en comptant les
chiffres successifs du mot précédent. Le deuxième mot est "11" parce qu’il y a un 1 dans "1". Ensuite, il y
a deux 1, donc le troisième mot est "21" etc. Voici les 8 premiers mots :

1
11
21
1211
111221
312211
13112221
1113213211

a) Écrire une méthode récursive MotSuivant() qui prend en paramètre un mot (par exemple "111221”), et
retourne le mot suivant.
Idée : par exemple pour 111221, le voir comme 111 221. Le mot suivant est alors formé du nombre de
répétitions (3) du premier chiffre, suivi de ce chiffre (1), suivi du mot qui suit 221.
b) Ecrire une méthode Main qui lit au clavier un entier positif n et affiche les premiers n mots partant du
mot "1".
67
Indiquer la signature (prototype) de chacune des méthodes en choisissant à chaque fois le mode de
passage des paramètres le mieux adapté:
a) SigneProd qui prend en paramètre deux entiers (int) et retourne le signe de leur produit (1 si ≥0 et -1
si <0).
b) CountZPN qui prend en paramètre un tableau contenant des valeurs entières. Elle place dans son
second paramètre le nombre de valeurs négatives, dans son troisième paramètre le nombre de valeurs
positives, et retourne le nombre de valeurs nulles.
c) PurgeTab qui prend en paramètre un tableau de float et purge (supprime) les répétitions dans ce
tableau. Elle retourne le nombre de valeurs supprimées.
d) Pgcd2 qui prend en paramètre 2 entiers (int) et remplace le second par le pgcd des deux.
e) Split qui prend en paramètre 3 tableaux d'entiers. Le premier contient des valeurs entières. Elle alloue
de l'espace mémoire pour le second et le troisième tableau et place dans le second tableau les valeurs
positives et dans le troisième tableau les valeurs négatives.
f) Agrandir qui prend en paramètre un tableau contenant des valeurs réelles ainsi qu'un entier nValSup et
agrandit le tableau en lui ajoutant nValSup nouvelles cases.

Exercices non résolus

68
Trouver la sortie écran du programme suivant (justifier votre réponse) :

struct MyStruct { public static void Func(MyStruct s) { static void Main() {


public int n ; s.n++; int k;
public int[] t ; for (int i=0;i<s.Length;i++) MyStruct ms;
} s.t[i]++; ms.n = 20;
} ms.t = new int[6];
for (k=0;k<6;k++)
ms.t[k] = k;
Func(ms);

Console.WriteLine(ms.n);
for (k=0;k<6;k++)
158 Chapitre V

Console.Write("{0}\t",
ms.t[k]);
}

69
Donner les signatures (prototypes) des méthodes F1, F2, F3, F4 et F5 compatibles avec leur utilisation
dans la méthode Main() suivante:
Static void Main()
{
int[] T=new int[10]; float B; char C; int A;
F1(T, A); C = F2( ref A, B, T[4] ); A = F3( out A, ref C, out B );
B = F4(); T[3] = F5( C, F4(), A )/5;
}
70
Ecrire une méthode Alterer() qui prend en paramètres deux chaînes de caractères s1 et s2 et forme la
chaîne s2 en y plaçant alternativement un caractère de gauche et un de droite de la chaîne s1. Par
exemple, si s1 contient la chaîne "IFRAIUEQTMON", alors s2 contiendra la chaîne
"INFORMATIQUE".
71
Dans un protocole de transmission, on considère un entier de type ulong (de taille variable suivant la
machine). Le bit du plus fort poids (le plus à gauche) est utilisé comme bit de parité paire (parity bit ou
check-bit). La valeur de ce bit doit être positionnée (à 1 ou à 0) de façon à ce que le nombre total de bits
égaux à 1 soit pair. Ceci permet la vérification du bon déroulement de la transmission des données à
distance. Par exemple, sur 8 bits, si l'on doit transmettre la valeur 38 = (100110)2, alors on transmet la
valeur 166 = (10100110)2. Si l'on doit transmettre la valeur 46 = (101110)2, alors on transmet 46 =
(00101110)2.
Ecrire les deux méthodes suivantes:
a) Transmettre() qui retourne l'entier à transmettre après avoir adjoint à son paramètre A son code de
parité.
b) Recevoir() qui vérifie la valeur du bit de parité de son premier paramètre (qui est la valeur reçue): si
le bit de parité n'est pas juste, la méthode retourne false, et si ce bit est juste, la méthode retourne
true après avoir placé dans son second paramètre la valeur réellement transmise (sans bit de parité).
72
On désire écrire un programme de cryptage d'un texte. Un cryptage consiste en un codage secret du texte,
le secret consistant en la connaissance d'une "clé" uniquement par le codeur et le décodeur du texte. Il
existe plusieurs méthodes de cryptage de texte, chacune ayant un algorithme et un type de clé différents.
Dans la méthode exposée ci-après, la clé k est un entier positif non nul. Considérons le texte suivant:

LE JOUEUR 1 PENSE A UN NOMBRE, SOIT X. LE JOUEUR 2 PENSE A UN AUTRE NOMBRE, SOIT


Y.

Supposons pour l'exemple, que k = 5. L'algorithme de cryptage consiste à réordonner les caractères du
texte en les alignant sur k lignes (de haut en bas) comme suit (pour plus de clarté dans la présentation de
cet exemple, on a remplacé les espaces par le caractère '-' (chose que vous ne devez pas faire!):

L U 1 S U M - - E E - E N R M - -
E E - E N B S X - U P - - E B S Y
- U P - - R O . J R E A A - R O .
J R E A N E I - O - N - U N E I
O - N - O , T L U 2 S U T O , T

Le texte crypté s'obtient en complétant d'abord les lignes incomplètes par le caractère '?' puis en
juxtaposant les caractères des k lignes:

LU1SUM--EE-ENRM--EE-ENBSX-UP--EBSY-UP--RO.JREAA-RO.JREANEI-O-N-UNEI?O-N-
O,TLU2SUTO,T?
Énoncés des exercices 159

a) Ecrire une méthode Crypter(clair, codage, cle) qui effectue le cryptage de la chaîne clair dans la
chaîne code en appliquant l'algorithme présenté ci-dessus avec une clé cle. Les chaînes sont de type
string et la clé est de type ushort. La méthode ne doit pas déclarer de chaîne ni de tableaux
supplémentaires.
b) Ecrire une méthode Decrypter(clair, codage, cle) qui effectue le décryptage de la chaîne code dans la
chaîne clair en appliquant l'inverse de l'algorithme de cryptage.
73
a) Ecrire une méthode OrdonnerChiffres() qui prend en paramètre un entier positif a (<1000) et
retourne un autre entier positif formé par les chiffres de a ordonnés par ordre croissant de gauche à
droite. Par exemple, si a=265 alors la méthode retourne 652.
b) Ecrire une méthode InverserChiffres() qui prend en paramètre un entier positif a (<1000) et retourne
un autre entier positif formé par les chiffres de a pris dans l'ordre inverse. Par exemple, si a=265
alors la méthode retourne 562.
c) Ecrire une méthode Kaprekar() qui prend en paramètre un entier positif a, soit 265, ordonne les
chiffres de a par valeurs croissantes, soit 256, inverse l'ordre, 652, et soustrait le premier du dernier:
652 - 256 = 396.
On en fait de même pour 396:
963 - 369 = 594,
puis pour 594:
954 - 459 = 495.
L'opération est répétée au plus 5 fois jusqu'à l'obtention de 495. La méthode retourne alors le
nombre de répétitions qui ont été nécessaires. Si le nombre 495 n'est pas obtenu au bout d'au plus 5
répétitions, alors la méthode retourne 0.
Remarque intéressante: Si on part d'un entier a de trois chiffres non tous égaux, et on applique la
méthode Kaprekar(a), il en résulte toujours 495, quelque soit a, et ce au bout d'au plus 5 itérations.

74
On dispose d'une chaîne contenant un texte écrit avec l'alphabet français. On désire générer une autre
chaîne contenant le cryptage (codage secret) du texte de la première chaîne de la façon suivante: chaque
lettre minuscule (a...z) est décalée de k positions vers la droite, et tous les autres caractères (lettres
majuscules, ponctuation, autres) restent inchangés. Le décalage se fait circulairement, c'est-à-dire que si
par exemple, k=5, la lettre a devient f, b devient g, i devient n, w devient b, et z devient e.
Ecrire une méthode Crypter() qui prend en paramètre deux chaînes de caractères et la valeur de la clé k et
effectue le cryptage de la première chaîne dans la seconde.
75
Deux chaînes de caractères sont dites "amies" si le nombre de lettres majuscules de l’une est égal au
nombre de lettres minuscules de l’autre ou vice-versa. Ecrire une méthode ChainesAmies qui prend en
paramètres deux chaînes de caractères et retourne true si elles sont amies et false sinon.
76
Deux chaînes de caractères sont dites "inverses" si l’une est la lecture en sens inverse de l’autre et vice-
versa, comme par exemple les chaînes "liban" et "nabil". Ecrire une méthode ChainesInverses qui prend
en paramètres deux chaînes de caractères et retourne true si elles sont inverses et false sinon.
77
Une chaîne de caractères w est un carré s'il existe une chaîne u telle que w = uu (par exemple "chercher"
et "bonbon" sont des carrés). Ecrire une méthode ChaineCarre() qui retourne true si la chaîne passée en
paramètre est un carré et false sinon.
78
Un entier positif K à n chiffres est dit nombre de Kaprekar si lorsqu'on élève K au carré, la somme du
nombre composé des n chiffres de droite et du nombre composé des n ou n-1 chiffres de gauche redonne
le nombre d'origine.
Exemples : 9, 45 et 297 sont des nombres de Kaprekar:
92 = 81 et 1+8=9, 452 = 2025 et 25+20=45 2972 = 88209 et 209+88 = 297

a) Ecrire une méthode Longueur() qui retourne le nombre des chiffres de son paramètre entier.
b) Ecrire une méthode Decompose() qui prend en paramètre 4 entiers M, n, M1 et M2 et détermine M1
et M2 comme suit: M1 est composé des n chiffres de droite de M (si M=1234, n=3, M1=234) et M2
160 Chapitre V

est composé des chiffres restants (si M=1234, n=3, M2=1). On supposera que n est inférieur ou égal
au nombre de chiffres de M (s'il est égal, alors M1=M et M2=0).
c) Ecrire une méthode Kaprekar() qui prend en paramètre un entier et retourne true si c'est un nombre
de Kaprekar et false sinon.
d) Ecrire une méthode Main() permettant de lire une limite L et de trouver tous les nombres de
Kaprekar inférieurs à cette limite.
79
Ecrire une méthode GeneratePassword() qui prend en paramètre une chaîne de caractères pass et un
entier n et génère dans pass une chaîne aléatoire en respectant les contraintes suivantes:
n
 La chaîne produite doit avoir une longueur aléatoire comprise entre et n caractères.
2
 Seuls les lettres et les chiffres sont acceptables.
 Deux caractères consécutifs ne doivent pas être identiques.
80
Ecrire une méthode Invert() qui prend en paramètre un entier non signé de type ushort (supposé sur 16
bits) et retourne un autre entier non signé dont la représentation binaire est l'inverse de celle du
paramètre. Attention, il ne s'agit pas d'une complémentation à 1 bit-à-bit, mais d'une inversion de l'ordre
des bits de gauche à droite. Par exemple, si on inverse l'entier 14769 dont la représentation est
0011100110110001, on obtient l'entier 36252 dont la représentation est 1000110110011100.
81
Un graphe orienté est représenté par une matrice dite d'adjacence: c'est une matrice carrée de dimension
égale au nombre de nœuds du graphe et dont chaque case (i, j) contient 1 s'il existe un arc du nœud i vers
le nœud j, et 0 sinon.
Les nœuds du graphe sont numérotés de 0 à L-1, où L est la taille de la matrice. Voici un exemple de
matrice d'adjacence et du graphe correspondant:

5 0 0 0 1 0 1 0
 
6 0 0 1 0 0 0 0
1 0 0 1 0 0 1
 
3
4
0 1 1 0 1 0 0
1 0 0 0 1 1 0 
1 
0 0 0 0 1 0 0 0
 
2 0 1 0 1 0 1 0

a) Ecrire deux méthodes DegreEntrant() et DegreSortant() prenant en paramètres un graphe (matrice)


et un numéro de nœud et retournant respectivement le nombre d'arcs entrants et sortants de ce nœud,
ou -1 si le nœud n'appartient pas au graphe.
b) Ecrire une méthode itérative CheminExiste() qui prend en paramètre un graphe, un chemin et la
longueur du chemin, et retourne true si le chemin existe dans le graphe et false sinon. Le chemin est
un tableau contenant les numéros des nœuds du chemin dont on veut vérifier l'existence. Pour le
graphe g de l'exemple, l'appel CheminExiste (g, {5, 3, 1, 2, 3, 4, 4, 0}, 7) doit retourner true et l'appel
CheminExiste (g, {5, 3, 1, 2, 3, 6, 4, 0}, 7) doit retourner false.
Attention, la méthode doit vérifier l'existence des nœuds du chemin dans le graphe.
c) Ecrire une version récursive de la méthode CheminExiste().
82
On désire crypter une chaîne de caractères en appliquant l'algorithme de substitution suivant: la clé est
une chaîne de 26 caractères contenant successivement le remplaçant de chacune des lettres de l'alphabet
de 'A' à 'Z'. Par exemple, si la clé est le tableau suivant:
QWERTYUIOPASDFGHJKLZXCVBNM

alors on doit remplacer A par Q, B par W, C par E, ..., Z par M.


Énoncés des exercices 161

Tous les autres caractères (lettres minuscules, chiffres, espacement, ponctuation et autres) restent
inchangés.
Par exemple, la chaîne claire suivante:
CE N'EST QU'UN petit EXEMPLE (1), NE TRAVAILLEZ SURTOUT PAS SUR ça!
SINON, VOUS N'AUREZ QU'UNE NOTE minable.
sera crypté en:
ET F'TLZ JX'XF petit TBTDHST (1), FT ZKQCQOSSTM LXKZGXZ HQL LXK ça!
LOFGF, CGXL F'QXKTM JX'XFT FGZT minable.

a) Ecrire une méthode Crypter() qui prend en paramètre deux chaînes de caractères (claire et cryptée)
ainsi que la chaîne représentant la clé, et effectue le cryptage suivant la méthode expliquée.
b) Ecrire la méthode de décryptage prenant les mêmes paramètres.
83
Pour communiquer efficacement sur une ligne Internet un carré 3×3 contenant des entiers positif tous
entre 0 et 7, on le code dans un seul entier de type int supposé sur 32 bits comme dans l'exemple suivant
(mais ce n'est qu'un exemple):
5 2 1
0 3 7
6 4 2
2 3 3 3 1 3 3 3 1 3 3 3 1

00 101 010 001 0 000 011 111 1 110 100 010 0

1ère ligne 2ème ligne 3ème ligne


2 bits non utilisés
et toujours nuls Bit de parité paire
des 9 derniers bits

Le bit de parité paire de chaque 9-uplet de bits doit à chaque fois être positionné à 1 ou à 0 de façon à
ce que le nombre de bits mis à 1 parmi les (9+1) bits soit toujours pair.

a) Ecrire une méthode Correct() qui prend en paramètre un carré codé dans un seul entier de type int
et retourne true si les 3 bits de parité sont correctement positionnés et false sinon.
b) Ecrire une méthode Profit() qui prend en paramètre un carré codé dans un seul int et retourne le
nombre de lignes (0 si aucune ligne, 1, 2 ou 3 lignes) dont les valeurs des trois codes sont égales.
84
On sait que la limite des entiers positifs représentables en C# est limitée (pour le type ulong, dans
l'intervalle [0, +18446744073709551615]). Lorsqu'on désire manipuler des entiers plus larges, on est
alors obligé de définir notre propre type et d'écrire les opérateurs correspondants (+, -, …). Dans ce
problème, nous décidons de stocker les nombres entiers non signés dans une chaîne de caractères de type
string et nous ne gérons ici que les entiers positifs.
Ecrire alors les méthodes C# suivantes (dans chaque méthode, vous avez le droit de faire appel à toute
méthode écrite):
a) Additionner(s1, s2, s): méthode qui place dans la chaîne s la somme des nombres représentés par les
chaînes s1 et s2, et retourne true si ces deux chaînes sont correctes, et false si l'une d'elles contient un
caractère qui n'est pas un chiffre.
b) SupprimerZeros(s): méthode qui supprime les zéros à gauche de la chaîne s.
c) PlusGrand(s1, s2): retourne true si le nombre représenté par s1 est strictement supérieur au nombre
représenté par s2, et false sinon. On suppose ici que les deux chaînes sont correctes.
d) Retrancher(s1, s2, s): méthode qui place dans la chaîne s la différence des nombres représentés par les
chaînes s1 et s2, c'est-à-dire (s1-s2) et retourne true si ces deux chaînes sont correctes, et false si la
différence va être négative ou si l'une des deux chaînes contient un caractère qui n'est pas un chiffre.
e) Multiplier(s1, s2, s): méthode qui place dans la chaîne s le produit des nombres représentés par les
chaînes s1 et s2, et retourne true si ces deux chaînes sont correctes, et false si l'une d'elles n'est pas
162 Chapitre V

correcte. N'essayez pas de programmer l'algorithme de multiplication qu'on utilise à la main car ceci
risque d'être trop compliqué. Essayer plutôt de réfléchir!
f) Diviser(s1, s2, s): méthode qui place dans la chaîne s le quotient de la division entière des nombres
représentés par les chaînes s1 et s2, c'est-à-dire (s1 / s2).
85
On considère un tableau d'entiers tab1 qui contient beaucoup de répétitions. On désire écrire en C# une
méthode Resumer(tab1, n1, tab2, n2) qui permet de résumer le tableau tab1 de taille n1 en plaçant dans
le tableau tab2 à chaque fois la valeur répétée suivie du nombre de répétitions adjacentes. On placera
enfin dans n2 la taille du tableau tab2. Par exemple, si le tableau tab1 contient les valeurs suivantes: 4 4 4
4 4 4 8 8 8 -2 -2 -2 -2 -2 -2 -2 9 8 8 8 8 8, alors le tableau tab2 contiendra les valeurs: 4 6 8 3 -2 7 9 1 8 5,
et n2 sera affectée de la valeur 10. Le tableau tab2 est supposé non alloué.
86
Il s'agit de programmer un jeu appelé "Jeu du Pendu". Le programme va proposer un mot dont
l'utilisateur doit deviner les caractères (pas forcément dans l'ordre). On suppose alors qu'on dispose d'une
méthode TirerMot(n) qui retourne le mot numéro n d'un dictionnaire à chaque fois qu'on y fait appel avec
un entier n compris entre 1et 1000. On a alors intérêt à choisir n aléatoirement pour obtenir un mot
différent à chaque jeu.
À chaque jeu, on utilise un tableau de 10 booléens pour mémoriser si chacun des lettres du mot à deviner
a été découvert ou non. On suppose que tous les mots sont formés de 10 lettres pas forcément tous
différents. Le joueur gagne un jeu s'il devine les 10 lettres du mot avant de commettre 11 erreurs, sinon il
perd le jeu. Une erreur consiste à proposer une lettre qui ne fait pas partie du mot à deviner. Le joueur ne
doit pas forcément deviner l'emplacement exact d'une lettre dans le mot. Si une lettre proposée par
l'utilisateur existe dans le mot, alors il suffit de mettre la case correspondante du tableau de booléens à
true.
Exemple: si le mot à deviner est "maquillage", et si le joueur a déjà entré ’i’, 'c', 'x', ’a’ et ’s’, alors le
tableau de booléens contient {false, true, false, false, true, false, false, true, false, false}.
a) Ecrire une méthode Afficher() qui prend en paramètre le mot à deviner et le tableau de booléens, et
afficher le résultat courant; par exemple pour le mot "maquillage", si le joueur a déjà entré ’i’, 'c', 'x',
’a’ et ’s’, alors la méthode affiche "*a**i**a**".
b) Ecrire une méthode Esssai() qui prend en paramètre le mot à deviner et le tableau de booléens, et
demande à l'utilisateur de proposer une lettre, puis met à jour le tableau de booléens.
c) Ecrire une méthode Reste() qui prend en paramètre le tableau de booléens et retourne le nombre de
caractères restant à trouver dans le mot à deviner. Exemple : pour "maquillage", si le joueur a déjà
entré ’i’, 'c', 'x', ’a’ et ’s’, alors il reste 7 caractères à trouver (’m’,’q’,’u’,’l’,’l’,’g’,’e’).
d) Ecrire une méthode JeuPendu() qui fait jouer l'utilisateur une seule fois au jeu du pendu. La méthode
doit tout d'abord tirer un mot au hasard à partir du dictionnaire, puis faire appel aux fonctions déjà
écrites jusqu'à ce que le joueur devine le mot ou commet 11 erreurs. Après chaque caractère entré par
l'utilisateur, la méthode doit afficher le résultat ainsi que le nombre d'erreurs.
e) Ecrire une méthode Main() qui propose une suite de plusieurs jeux du Pendu, tant que le joueur
répond oui pour continuer.
87
a) Définir un type Point qui est une structure formée des coordonnées (entiers) x et y d’un point.
b) Ecrire une méthode Distance() qui retourne la distance, au sens géométrique usuel, entre les points
p1 et p2 passés en paramètre.
c) Ecrire une méthode PlusEloigné(Point p, bool[,] image) qui prend en paramètre un point p et une
matrice image, et retourne le point allumé de l’image qui est le plus éloigné du point p. L’image est
donnée sous la forme d’un tableau rectangulaire : une case de ce tableau de valeur true représente un
point allumé.
Énoncés des exercices 163

On supposera que l’image contient toujours au moins un point allumé. On pourra utiliser l’algorithme
suivant:
– créer une structure pos de type Point ;
– mettre p dans pos ;
– pour chacune des positions [i,j] de l’image: si le point de position [i,j] est allumé, et si la distance entre
les points de positions p.x et p.y et [i,j] est supérieure à la distance entre le point p et le point dont la
position est stockée dans pos, alors stocker i et j dans pos ;
– retourner pos.
88
Un photocopieur accepte les touches '>' pour agrandir de 5%, '<' pour réduire de 5% et 'S' pour
commencer la photocopie d'une page. La taille normale de la copie est de 100%. Ecrire une méthode
Taille() qui prend en paramètre une chaîne de caractères représentant la série des touches
d'agrandissement/réduction et retourne la taille (en pourcent) de la copie. Exemples:
Taille("S")  100 Taille(">>>S") 115
Taille("><<<<><<>S")  85
89
On désire écrire un programme de facturation des abonnés d'un fournisseur de connexion Internet. Un
abonné peut posséder plusieurs comptes internet. Il existe trois types de débit pour un compte: 128 MB à
8$/mois, 256 MB à 12$/mois et 512 MB à 24$/mois. La taille de consommation de base est de 30
GB/mois et chaque GB supplémentaire sera facturé 2$. Une fraction de GB sera facturé 1 GB entier.
On donne les définitions suivantes:

struct Personne {
public string nom, prenom, adresse;
}
struct CompteInternet
{
public string username; // identificateur du compte internet
public int debit; // 128, 256 ou 512 MB
public float consom; // consommation mensuelle en GB, par exemple: 6.43 GB
}
struct UnAbonne
{
public Personne person; // personne abonnée
public int nbComptes; // nombre de comptes internet de cet abonné
public CompteInternet[] comptes; // tableau des comptes Internet de cet abonné
}
struct Fournisseur
{
public int NbAbonnes; // Nombre d'abonnés du fournisseur
public UnAbonne[] abonnes; // tableau des abonnés
}

Ecrire les trois méthodes suivantes (chacune peut faire appel aux précédentes):

a) FactureCompte(): prend en paramètre une structure de type CompteInternet et retourne la somme que
doit payer l'abonné pour ce compte.
164 Chapitre V

b) FactureAbonne(): prend en paramètre une structure de type UnAbonne et retourne la somme que doit
payer un abonné pour l'utilisation de tous ses comptes internet.
c) Lister(): prend en paramètre une structure de type Fournisseur et affiche à l'écran (une ligne par
abonné) le nom, le prénom et la somme totale que doit payer chaque abonné.
90
a) Ecrire une méthode Inc() qui prend comme premier paramètre un tableau tab1; ce tableau est
supposé rempli avec des valeurs réelles (float). elle prend aussi un second paramètre tab2 d’entiers
pour lequel la méthode doit allouer de la mémoire de la même taille que celle de tab1, puis, pour
chaque case de tab2, remplir la case correspondante dans tab2 avec la longueur de la suite croissante
de valeurs commençant à cet indexe dans tab1. Par exemple:

0.85 0.82 0.93 0.90 0.95 0.99 1.02 0.97 1.05 1.07 0.92 0.96
tab1
Inc

1 2 1 4 3 2 1 3 2 1 2 1
tab2
b) Ecrire une méthode LongestInc() qui prend en paramètre un tableau de floats, et retourne l’indice de
début de la plus longue suite croissante de valeurs dans ce tableau. Cette méthode doit aussi placer la
longueur de cette suite dans son deuxième paramètre. Par exemple, appliqué sur tab1 de l’exemple
précédent, LongestInc retourne 3 et place 4 dans son second paramètre. Cette méthode peut faire
appel à la méthode Inc de la question précédente.
c) Ecrire une méthode Main() de test. Elle doit lire au clavier la taille et les valeurs d’un tableau, et
afficher l’indice de début de la plus longue suite croissante de valeurs dans ce tableau, ainsi que la
longueur de cette suite.
91
Considérons les définitions suivantes:
struct Player {
public string name, firstname, nationality;
public int number, birthYear;
}
struct Team {
public string country;
public Player[] players;
}
struct Goal {
public int playerNumber;
public int minute, second; // time of the goal
}
struct Game {
public Team team1, team2;
public int score1. score2; // scores of team1 and team2
public Goal[] players1, players2; // goals players
}
struct Games {
public int nbGames; // number of games
public Game[] games;
}
a) Ecrire une méthode DispGame() qui prend en paramètre une structure g de type Game et affiche à
l’écran les pays des deux équipes et les noms des joueurs qui ont placé les buts dans ce jeu.
b) Ecrire une méthode DispGames() qui prend en paramètre une structure gs de type Games et affiche
tous les jeux comme dans la question précédente.
c) Ecrire une méthode Winner() qui prend en paramètre une structure gs de type Games et affiche le pays
gagnant ( ayant le score total le plus élevé).
Énoncés des exercices 165

92
Ecrire une méthode récursive Convert(uint n, out string s, int b) qui convertit l’entier positif n de la base
10 à la base b et place le résultat dans la chaîne de caractères s.
93
Considérons le programme suivant :
public static void main () {
int[] tab = new int[7];
tab[tab.length-1] = 1;
for (int i=tab.length-2; i>=0; i=i-1) tab[i] = tab[i+1]*2;
Console.WriteLine("result = {0}" , g(tab));
int d = 2;
f(tab, d);
Console.WriteLine ("result = {0}" , g (tab));
}
public static int g (int[] t) {
int n = 0;
for (int i=0; i<t.length; i=i+1) n = n + t[i];
return n;
}
public static void f (int[] t, int i) {
if (i != 0) {
for (int j=0; j<t.length-1; j=j+1) t[j] = t[j+1];
t[t.length-1] = 0;
f(t, i-1);
}
}
a) Quel est l’affichage produit par ce programme?
b) Écrire en une phrase l’opération que la méthode f exécute sur le tableau t en fonction de i.
94
Considérons les définitions suivantes :
struct Time {
public int hour, min;
}
struct Date {
public int day, month, year ; public Time time ;
}
struct Passenger { // Passager
public string id, name, address, tel ;
}
struct City {
public string id, name, country ;
}
struct Airport { // Aéroport
public string name ;
public City city; // Ville de l’aéropot
}
struct Flight { // un Vol
public string id, number ;// id et numéro du vol
public Date departureDate, arrivalDate ;
public string company ; // compagnie de voyage
public Airport departureAirport, arrivalAirport ;
}
struct Reservation {
public string id ;
public Date reservationDate;
public Flight flight ;
public Passenger passenger ;
}
struct Agency { // agence de voyage
166 Chapitre V

public string name ;


public int nbReserv ; // Nombre de réservations
public Reservation[] reserv ; // tableaux des réservations effectuées
}
Ecrire les méthodes suivantes :
a) FlightReservNumber() : prend en paramètre une structure Agency supposée remplie de données, et
l’id d’un vol, et retourne le nombre de réservations de cette agence sur ce vol.
b) PassengerFlights() : prend en paramètre une structure Agency supposée remplie de données, et l’id
d’un passager, et affiche à l’écran tous les vols (1 vol par ligne) réservés pour ce passager sous la
forme suivante :
c)
NV Comp V/P Dép V/P Ar J/M/A/h:m Dép
… ……. ……… ……… ……………..
… ……. ……… ……… ……………..

où :
NV est le numéro du vol,
Comp est la compagnie du vol,
V/P Dép est la Ville et le Pays de départ du vol,
V/P Ar est la Ville et le Pays d’arrivée du vol,
J/M/A/h:m Dép est le Jour/Mois/An/Heure/Minute de départ du vol.
d) FlightsFromTo() : prend en paramètre un tableau de type Flight supposé rempli de données, une ville
de départ de type City, une ville d’arrivée de type City, et affiche à l’écran tous les vols allant de la
ville de départ à la ville d’arrivée sous la forme suivante :

NV Comp J/M/A/h:m Dép


… ……. ……………..
… ……. ……………..
e) CancelReservationId() : prend en paramètre une structure Agency ag et l’id d’une réservation et la
supprime de l’agence ag. La méthode doit retourner true si la suppression a bien eu lieu (id trouvé) et
false sinon.
f) HasReservation() : prend en paramètre une structure Agency supposée remplie de données, et l’id
d’un vol, et retourne true si la personne dont le nom est passé en 3ème paramètre possède une
réservation sur ce vol et false sinon.
g) ChangeAirportName() : un aéroport a changé de nom. Cette méthode prend en paramètre une
structure Agency supposée remplie de données, le nom d’un aéroport et son nouveau nom (string), et
modifie dans toutes les réservations de cette agence, le nom de l’aéroport en question.
h) Flights4() : prend en paramètre une structure Agency supposée remplie de données, les noms de deux
aéroports (string) a1 et a2, et un tableau du type Flight sans aucune mémoire allouée ; la méthode doit
placer dans le tableau les premiers 4 vols (dans l’ordre trouvé) partant de l’aéroport a1 et arrivant à
l’aéroport a2.
95
Un entier est divisible par 11 si la différence entre la somme des chiffres de rang pair et la somme des
chiffres de rang impair (à partir du premier chiffre à droite à qui on affecte le rang 0) est divisible par 11.
Ecrire une méthode récursive IsDiv11() qui prend en paramètre un entier positif n qui retourne true si n est
divisible par 11 et false sinon. La méthode ne doit comporter aucune opération de division par 11 ou de
modulo 11.
Exemples :
Si n=651 alors (1+6) - 5=2 n'est pas divisible par 11. Alors 651 n'est pas divisible par 11.
Si n=121121 alors (1+1+2)-(2+1+1)=0 est divisible par 11. Donc, 121121 est divisible par 11.
96
On dit qu'un tableau d'entiers t est magique si pour chaque case d'indice i, la valeur de la case t[i] est le
nombre de cases dans le tableau contenant la valeur i. Par exemple, le tableau t de taille 4, avec les
éléments 1 2 1 0 est magique car t[0] = 1 et le tableau t contient un 0, t[1] = 2 et le tableau t contient deux
1, t[2] = 1 et le tableau t contient un 2, t[3] = 0 et le tableau t ne contient pas de 3.
Énoncés des exercices 167

Ecrire une méthode TabMagic() qui a en paramètre un tableau d'entiers et qui retourne true si ce tableau
est magique et false sinon.
97
a) Ecrire une méthode NbSeq() qui prend en paramètre une matrice m d’entiers, et un tableau seq de
valeurs entières, et retourne le nombre de lignes de la matrice m dans lesquelles se trouve la séquence
des valeurs du tableau seq. Par exemple, si

4 1 10 12 7
𝑚= 1 11 12 1 10 et seq=[1, 10, 12],
12 13 1 10 12

alors la méthode retourne 2.


b) Modifier la méthode précédente pour qu’elle retourne un tableau contenant les indices des lignes qui
contiennent la séquence seq.
98
On considère la définition suivante :
struct Point { public int x, y ; }
a) Ecrire une méthode Longueur() qui prend en paramètre deux points et retourne la longueur (de type
float) du segment joignant ces deux points.
b) Écrire une méthode récursive Sierpinski() prenant en paramètre 3 points A, B et C permettant de
dessiner un triangle de Sierpinski. Étant donné ses trois sommets A, B et C, ce triangle est dessiné de la
manière suivante :
 dessiner le triangle ABC ;
 calculer D, E et F, respectivement les milieux des segments AB, BC et CA;
 dessiner les triangles de Sierpinski ADF, BED et CFE.
Le traçage d’un triangle n’est fait que si son périmètre est supérieur à 5.
On suppose l’existence d’une méthode DrawLine() qui prend en paramètre 2 points et trace le segment les
joignant.
99
Que fait cette méthode ?
int f(int n){
if(n<10) return 1;
else
return 1+f(n/10);
}
100
Ecrire une méthode récursive IsDigitInNumber(int d, int n) qui retourne true si le chiffre d apparaît dans le
nombre n et false sinon.
101
On considère les définitions suivantes:
struct Category {
public int catId ; //category id
public string catName, description ;
}
struct Product { // article
public int prodId; // product id
public int prodName; // product name
public int categoryId; // category id of this product
public float unitPrice;
public int unitsInStock; // quantity in stock
}
struct Order { // command for a client
public int orderId;
public string clientName;
}
struct OrderProduct { // one article of a command
public int orderId; // id of the order to which belongs this order product
168 Chapitre V

public int productId;


public int Quantity;// ordered quantity
}
struct Data {
public int nbCats ;// number of categories
public Category[] cats ; // array of categories
public int nbProds;// number of products
public Product[] prods; // array of products
public int nbOrds;// number of orders
public Order[] ords; // array of orders
public int nbOrdProds;// number of order products
public OrderProduct[] ordProds; // array of order products
}

Chaque produit (Product) appartient à une catégorie. Un ordre est formé d’un ou de plusieurs produits.
Ecrire les méthodes suivantes:
a) DisplayCategory() qui prend en paramètre:
 Une structure data de type Data ;
 l’id d’une catégorie ;
et affiche tous les noms des produits de cette catégorie.
b) CategoryValue() qui prend en paramètre:
 Une structure data de type Data ;
 le nom d’une catégorie ;
et retourne le prix total des produits de cette catégorie.
c) OrderValue() qui prend en paramètre:
 Une structure data de type Data ;
 l’id d’une commande (order id)
et retourne le prix total de cette commande.
d) ClientOrdersValue() qui prend en paramètre:
 Une structure data de type Data ;
 le nom d’un client ;
et retourne le prix total de toutes les commandes de ce client. On pourra faire appel à la méthode
OrderValue().
102
Ecrire (sans faire appel aux méthodes de la classe String sauf la propriété Length) les méthodes suivantes:
a) LastIndexOf() : prend en paramètre une chaîne s et un caractère c et retourne l’indice de la dernière
occurrence de c dans s, ou -1 si s ne contient pas c.
b) Insert() : prend en paramètre une chaîne s, un indice n, et une chaîne ss, et retourne un tableau de
caractères contenant s dans laquelle on a inséré ss à partir de l’indice n de s. Si l’indice n n’est pas
acceptable, la méthode retourne null. Par exemple, Insert("abcdefghij", 3, "xyz") retourne le tableau
abcxyzdefghij ; et Insert("abcdefghij", 10, "xyz") retourne null.
103
Pour tester si un entier positif est divisible par 11, on peut procéder récursivement comme suit :
 extraire le chiffre des unités ;
 retrancher ce chiffre de l’entier privé de ce chiffre ;
 l’entier obtenu est divisible par 11 si et seulement si l’entier original l’est.
 Arrêter si l’entier obtenu est formé de deux chiffres. S’ils sont identiques, c’est divisible par 11.
Exemples :

24684  2468-4=2464  246-4=242  24-2=22. Donc 24684 est divisible par 11.
365016  36501-6=36495  3649-5=3644  364-4=360  36-0=36. Donc 36501 non divisible par 11.
Ecrire une méthode récursive IsDiv11() qui prend en paramètre un entier positif et retourne true s’il est
divisible par 11 et false sinon, en appliquant l’algorithme ci-dessus.
104
𝑛/2 𝑆𝑖 𝑛 𝑒𝑠𝑡 𝑝𝑎𝑖𝑟
Soit la fonction dite de Syracuse définie par: 𝑆𝑦𝑟𝑎𝑐𝑢𝑠𝑒(𝑛) = { }
1 + 3𝑛 𝑆𝑖 𝑛 𝑒𝑠𝑡 𝑖𝑚𝑝𝑎𝑖𝑟
Énoncés des exercices 169

a) Ecrire une méthode Syracuse() qui prend en paramètre un entier positif n et qui répond à cette définition.

Une suite de Syracuse est définie à partir d’un entier naturel u0 ≠ 0 par :

∀ 𝑛 > 0, 𝑢𝑛+1 = 𝑆𝑦𝑟𝑎𝑐𝑢𝑠𝑒(𝑢𝑛 ).

On admettra que ces suites possèdent la propriété (P) : ∀ 𝑢0 ≠ 0, ∃ 𝑛; 𝑢𝑛 = 1 (la suite atteint toujours 1).
Par exemple, si u0=2, alors u1=1 et (P) est vraie. Si u0=5, alors u1=16, u2=8, u3=4, u4=2, u5=1.

b) On nomme "orbite de p" la liste des termes de la suite de Syracuse avec u0 = p, jusqu’à l’occurrence du premier
1. Par exemple, orbite de 3 : (3 10 5 16 8 4 2 1), et orbite de 1 : (1). Ecrire une méthode Orbite() qui
prend en paramètre un entier positif p et retourne l’orbite de p dans une chaîne de caractères dans laquelle les
termes sont séparés par un espace.
c) On nomme "apogée d’une orbite" le plus grand entier de cette orbite. Par exemple, l’apogée de 3 est 16. Ecrire
une méthode Apogee() qui prend en paramètre un entier positif p et retourne l’apogée de l’orbite p.
d) Ecrire la méthode Apogees() qui prend en paramètre deux entiers positifs p et q tels que q>p>0 et retourne un
tableau d’entiers contenant toutes les apogées de i pour i entre p (inclus) et q (exclu).

105
On considère la figure suivante :

Cette figure est formée d’un cercle initial et de deux copies de ce cercle ayant subies une réduction d’un
facteur 2, ces deux petits cercles étant tangents extérieurement au cercle initial et tels que les lignes des
centres sont parallèles aux axes du repère (x en horizontal et y en vertical).
Ces deux petits cercles deviennent à leur tour cercle initial pour poursuivre la figure récursivement.
On suppose l’existence d’une fonction DrawCircle(xc, yc, r) qui trace graphiquement un cercle de centre
(xc,yc) et de rayon r.
Ecrire une méthode récursive DrawImage() qui prend en paramètre les coordonnées et le rayon du cercle
initial et trace la figure donnée. Le traçage s’arrête lorsque le rayon d’un cercle initial devient inférieur ou
égal à 1.
La figure donnée correspond à l’appel DrawImage(0, 0, 8).

106
Ecrire une méthode Alternatif() qui prend en paramètre un tableau d’entiers et le nombre d’éléments et
retourne true si les signes des éléments sont alternés, et false sinon. Par exemple :

2 -3 17 -1 4 5 -1 8 -9 3 false
12 -3 3 -8 33 -2 1 -8 11 -3 true
-6 15 -4 2 -3 2 -9 8 -6 36 true
107
Ecrire une méthode récursive RecMin() qui prend en paramètre un tableau d’entiers et son nombre
d’éléments et retourne la valeur minimale du tableau.

108
L’objectif ici est d’écrire une fonction qui lisse un signal (donné sous la forme d’un tableau de réels). Le
lissage se fait en calculant la i-ème valeur du nouveau signal comme étant la moyenne des valeurs du
signal initial à l’intérieur d’une fenêtre de taille impaire donnée, supérieure ou égale à 1, centrée en i.
Attention pour les premières et dernières valeurs, seules les valeurs dans la fenêtre sont prises en compte.
170 Chapitre V

L’exemple suivant montre le lissage d’un signal avec une fenêtre de longueur 3.

a) Ecrire une méthode SignalLisse3() qui prend en paramètre un premier tableau contenant le signal,
ainsi que sa taille n, et un second tableau supposé non alloué destiné à contenir le signal lisse, et
effectue le lissage avec une fenêtre de longueur 3.
b) Ecrire une méthode SignalLisse() similaire à la méthode précédente, mais qui prend aussi un
paramètre f représentant la taille de la fenêtre, et effectue le lissage avec une fenêtre de longueur f.
109
Considérons les définitions suivantes :
struct User
{
public string username, password, lastname, firstname, country, email ;
public DateTime creationDate; // creation date of the user account
}
struct Tweet
{
public int id; // the tweet id
public string username; // username of the user who has published this tweet
public string text; // the tweet text
public DateTime publishDate;
}
struct Following
{
public string followerUsername, followedUsername;
}
struct Users
{
public int nbUsers;
public User[] users;
}
struct Tweets
{
public int nbTweets;
public Tweet[] tweets;
}

struct Followings
{
public int nbFollowings;
public Following[] followings;
}
struct Tweeter
{
public Users users;
public Tweets tweets;
public Followings followings;
}

Sur le système tweeter, un utilisateur peut suivre (follow) un ou plusieurs utilisateurs et peut être suivi
(flollowed) par un ou plusieurs utilisateurs. Ainsi, lorsqu’un utilisateur publie un Tweet (message, comme
Énoncés des exercices 171

le status sur facebook), ce Tweet est affiché sur la page de tous ses suiveurs (floowers). De même,
lorsqu’un utilisateur se connecte, il voit les tweets de tous les utilisateurs dont il est suiveur (followed).

Ecrire les méthodes suivantes:

a) CountryFollowers(): prend en paramètre une structure de type Tweeter et un username, et retourne le


nombre de suiveurs (flowers) de ce user qui sont du même pays que le sien.
b) TweetVisibility(): prend en paramètre une structure de type Tweeter et l’id d’un tweet, et affiche à
l’écran les noms et prénoms de tous les utilisateurs qui peuvent voir ce tweet.
c) EmailAvailability(): prend en paramètre une structure de type Tweeter et un email (string), et affiche à
l’écran "Email non disponible depuis XXX" si cet email est déjà enregistré par un utilisateur (XXX
est la date de création de son compte), ou "Email disponible" si cet email n’appartient à aucun
utilisateur.
d) ChangeFirstname():(): prend en paramètre une structure de type Tweeter, un username et un nouveau
prénom (firstname), et remplace le prénom de cet utilisateur par le nouveau prénom passé en
paramètre. En cas de succès, la méthode retourne true, et false sic et utilisateur n’existe pas.

Vous aimerez peut-être aussi