ESIEE IGI-3005TP no 3 (deux séances) (corrigé) 2014-2015 Tableaux (corrigé) Table des matières 1 Utilitaires 1.1 Affichage d’un tableau (*) . . . . . . . 1.2 Mise à zéro d’un tableau (*) . . . . . . 1.3 Remplissage d’un tableau aléatoire (*) 1.4 Remplissage d’un tableau aléatoire trié . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 2 3 3 2 Calcul sur les éléments d’un tableau 2.1 Somme des éléments d’un tableau (*) . . . . . . . 2.2 Moyenne des éléments d’un tableau (*) . . . . . . . 2.3 Résistance équivalente (**) . . . . . . . . . . . . . 2.4 Recherche d’éléments sur critère (*) . . . . . . . . 2.5 Maximum d’un tableau (*) . . . . . . . . . . . . . 2.6 Indice du maximum d’un tableau (*) . . . . . . . . 2.7 Un tableau est-il trié ? (*) . . . . . . . . . . . . . . 2.8 Recherche séquentielle dans un tableau trié (*) . . 2.9 Recherche dichotomique dans un tableau trié (**) . 2.10 Tests (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 4 5 6 6 7 7 8 8 3 Copie et décalage de tableaux (**) 3.1 Copie simple de tableaux (*) . . . . . . . 3.2 Copie sécurisée de tableaux (**) . . . . . 3.3 Décalage droite d’un tableau de réels (*) . 3.4 Décalage gauche d’un tableau de réels (*) 4 Les 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 chaînes de caractères Répétition (*) . . . . . . . . . . Retournement d’une chaîne(*) . Recherche de motif (1) (**) . . Recherche de motif (2) (**) . . Chercher/remplacer (*) . . . . Fréquence (1) (**) . . . . . . . Fréquence (2) (**) . . . . . . . Conversion chaîne de caractères 5 Pour aller plus loin 5.1 Mise en majuscules (**) . . . . 5.2 Classement alphabétique (***) 5.3 Des chiffres en lettres (**) . . . 5.4 Des nombres en lettres (****) . 5.5 Compteur de mots (***) . . . 5.6 Les huit reines (***) . . . . . . . . . . . . (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 9 11 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . en entier (**) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 12 12 12 13 13 14 14 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 17 17 18 23 24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tous les exercices sont à faire. Sont à rendre (par binôme) : – le programme de l’exercice 1.3 – les programme des exercices 2.7, 2.8 et 2.9 – les programme des exercices 3.3 et 3.4 – les programmes des exercices 4.2 et 4.8 Les exercices sont à envoyer à l’adresse [email protected] - objet obligatoire : IGI-3005 CR TP3 nom1 nom2 - fonctions C commentées en pièces jointes (pas de zip) –1/25– ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 Note : sauf spécification contraire, dans tous les exercices, on considérera que les tableaux contiennent au moins un élément. 1 Utilitaires 1.1 Affichage d’un tableau (*) Exercice 1. Écrivez la fonction qui affiche les n premiers éléments d’un tableau de réels. Prototype : void affiche_tab(double t[], int n); Corrigé *************************************************************************** void affiche(double t[], int n) { int i; for (i=0;i<n;++i) { printf("%10.5lf ",t[i]); } printf("\n"); } *************************************************************************** 1.2 Mise à zéro d’un tableau (*) Exercice 2. Écrivez la fonction qui remplit un tableau de n réels par des zéros ( 0.0 ). Prototype : double * raz(double t[], int n); Note : on retourne souvent pour une fonction opérant sur un tableau l’adresse de ce tableau, ce qui permet d’enchaîner les appels dans une seule ligne. Par exemple : affiche(raz(t, n), n); Corrigé *************************************************************************** double * raz(double t[], int n) { int i; for (i=0;i<n;++i) { t[i]=0.0; } return t; } *************************************************************************** –2/25– } *************************************************************************** 1.1 Calcul sur les éléments d’un tableau Somme des éléments d’un tableau (*) Exercice 5. } return t.i<n. t[0]=rand()/(double)RAND_MAX. Corrigé *************************************************************************** double * remplit_alea(double t[]. int n).3 TP no 3 (deux séances) (corrigé) 2014-2015 Remplissage d’un tableau aléatoire (*) Exercice 3.4 Remplissage d’un tableau aléatoire trié (*) Exercice 4. Ce genre de boucle est appelé schéma d’accumulation. int n) { int i.h .i<n.++i) { t[i]=rand()/(double)RAND_MAX. int n). L’écriture mathématique Σbi=a expr(i) s’écrira en C : –3/25– .++i) { t[i]=t[i-1]+rand()/(double)RAND_MAX. } return t. Corrigé *************************************************************************** double * remplit_trie(double t[]. for (i=1. int n). } *************************************************************************** 2 2. Prototype : double * remplit_trie (double t[]. int n) { int i. Écrivez la fonction qui remplit un tableau de n réels par des nombres pseudo-aléatoires en ordre croissant. Écrivez la fonction qui remplit un tableau de n réels par des nombres pseudo-aléatoires compris entre 0 et 1 Prototype : double * remplit_alea (double t[]. Écrivez une la fonction qui calcule la somme des n premiers éléments d’un tableau de réels Prototype : double somme (double t[]. on accumulera dans une variable les valeurs des éléments du tableau.ESIEE IGI-3005 1. for (i=0. Corrigé *************************************************************************** Le principe est de parcourir le tableau pour en calculer la somme : dans une boucle. Note : on se documentera sur la fonction C rand() déclarée dans stdlib. 3 Résistance équivalente (**) Exercice 7. int n).n)/n. et d’autre part de garder sous forme explicite le nombre d’éléments à traiter dans l’écriture du programme. ce qui permet d’une part de gagner une soustraction par tour de boucle. } *************************************************************************** 2. } return total. i < n .2 Moyenne des éléments d’un tableau (*) Exercice 6. ce qui conduirait à une division par 0. for (i=a. } *************************************************************************** 2. Un écueil à éviter est l’oubli du cas où un des éléments est nul.i<=b.0. Corrigé *************************************************************************** Il faut évidemment utiliser la fonction de l’exercice précédent (réutilisation) : double moyenne(double t[]. ++i) { total += t[i]. int n).0. int n) { return somme(t. La solution consiste à retourner directement 0 si l’un des éléments est nul. Écrivez une la fonction qui calcule la moyenne des n premiers éléments d’un tableau de réels Prototype : double moyenne (double t[]. –4/25– . Il vaut mieux écrire la condition de répétition sous la forme i < n que sous la forme i <= n-1 . Ce qui donne la solution possible suivante : double somme(double t[]. Corrigé *************************************************************************** C’est un schéma classique d’accumulation (somme des inverses des éléments du tableau). double total=0. int n) { int i.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 var=0. Le parcours séquentiel d’un tableau de n éléments en langage C se fait par une boucle allant de l’indice 0 à l’indice n-1 (inclus). Écrivez une fonction qui calcule la résistance équivalente d’un nombre quelconque de résistances en parallèle n X 1 1 Rappel : = Réq Ri i=1 Prototype : double resistance (double r[]. puis retour de l’inverse de l’accumulateur. for (i = 0 .++i) var += expr(i). 0. Prototype : int indice_premier_negatif (double t[]. Une erreur courante de programmation consiste à retourner -1 trop tôt.0. int n). Écrivez la fonction qui retourne l’indice du premier élément strictement négatif parmi les n premiers éléments d’un tableau de réels (-1 si aucun élément n’est négatif).4 Recherche d’éléments sur critère (*) Exercice 8. C’est toute la différence entre une recherche existentielle (∃i t[i] < 0) et une recherche universelle (∀i t[i] ≥ 0). avec un test du style if (t[i]<0) return i. –5/25– . l’analyse du problème nous conduit à la solution suivante : — on parcourt le tableau — si l’on rencontre un élément négatif. } *************************************************************************** 2.i<n.0) return 0. on termine la fonction en retournant l’indice courant — si l’on a parcouru l’intégralité du tableau sans avoir rencontré d’élément négatif. on retourne -1 comme indiqué dans la spécification. int n) { double req=0. for (i=0. else return -1. int i. Attention : c’est après la boucle que l’on peut constater l’absence d’élément négatif. ce qui conduit à retourner -1 si le premier un élément n’est pas négatif. } return 1/req. Corrigé *************************************************************************** Ici.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 double resistance (double r[]. req += 1/r[i].++i) { if (r[i]==0. ++i) { if (t[i]<0) return i. avec une mémorisation du plus grand élément rencontré. et la boucle peut commencer par l’indice 1. L’initialisation de cet indice maximum pourra se faire par l’indice du premier élément du tableau (0). Un parcours du tableau s’impose. s’il lui est supérieur. int n) { int i. avec une mémorisation de l’indice du plus grand élément rencontré. for (i=0.++i) { if (t[i]>maxi) maxi=t[i]. Corrigé *************************************************************************** Un parcours du tableau s’impose. } return maxi. en cours ou en fin de tableau) et donc on ne peut le connaître qu’après avoir examiné tous les éléments du tableau. Le corps de la boucle consistera à comparer l’élément courant au maximum. int n). Écrivez la fonction qui retourne la valeur du plus grand des n premiers éléments d’un tableau de réels Prototype : double valeur_plus_grand (double t[]. en cours ou en fin de tableau) et donc on ne peut le connaître qu’après avoir examiné tous les éléments du tableau . et le mémoriser permettra de le retourner en fin de parcours. Corrigé *************************************************************************** Le programme est semblable au précédent. En effet. l’indice du premier d’entre eux) Prototype : int indice_plus_grand (double t[]. et la boucle peut commencer par l’indice 1. int n) { int i. Écrivez la fonction qui retourne l’indice du plus grand des n premiers éléments d’un tableau de réels (en cas d’ex-æquo. mémoriser sa position permettra de la retourner en fin de parcours. Ce qui conduit à la solution suivante : –6/25– . à le mémoriser dans le maximum. le plus grand élément du tableau peut se situer n’importe où (en début.i<n.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 int indice_premier_negatif (double t[]. Ce qui conduit à la solution suivante : double valeur_plus_grand (double t[]. En effet. } *************************************************************************** 2. int n). double maxi=t[0]. L’initialisation de ce maximum pourra se faire par le premier élément du tableau ( t[0] ).5 Maximum d’un tableau (*) Exercice 9. } *************************************************************************** 2. i<n . for (i=1. } return -1.6 Indice du maximum d’un tableau (*) Exercice 10. et. le plus grand élément du tableau peut se situer n’importe où (en début. n[t[i] ≥ t[i − 1] Ce qui conduit à la solution suivante : int est_trie(double t[].8 Recherche séquentielle dans un tableau trié (*) Exercice 12.7 Un tableau est-il trié ? (*) Exercice 11. for (i=0 . ou la place où devrait se trouver x dans le tableau s’il est absent. for (i=1. ++i) { if (t[i] >= x) return i.++i) { if (t[i]<t[i-1]) return 0. } *************************************************************************** 2. } *************************************************************************** –7/25– . Écrivez la fonction qui retourne 1 si les n premiers éléments du tableau sont en ordre croissant (au sens large) et 0 sinon Prototype : int est_trie(double t[]. int n) { int i. Ce qui conduit à la solution suivante : int rech_seq_tab_trie(double x.i<n. for (i=1. double t[]. } *************************************************************************** 2. } return imax.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 int indice_plus_grand (double t[]. int n) { int i. Corrigé *************************************************************************** Comme le tableau est trié. int n).++i) { if (t[i]>t[imax]) imax=i. int n). } return 1. mixé à une recherche de sentinelle généralisée : le premier élément du tableau ≥ x.i<n. Écrivez la fonction qui retourne la position d’insertion éventuelle d’une valeur dans un tableau supposé trié (recherche séquentielle). Prototype : int rech_seq_tab_trie(double x. int n) { int i. } return n. Corrigé *************************************************************************** Un parcours de tableau à partir de l’indice 1 pour vérifier la propriété ∀i ∈ [1. int imax=0. i<n. Note : La fonction doit retourner la place du premier x dans le tableau s’il est présent. le programme revient à un parcours de tableau sur n éléments. double t[]. 0. 3.0. int pbs=0. –8/25– . L’algorithme du cours se traduit immédiatement en C : int rech_dicho_tab_trie(double x. int i. 1. /* pos<= f */ while (d+1 < f) { m = (d+f)/2.0. posd = rech_dicho_tab_trie(test_x[i]. 2. appeler rech_seq_tab_trie et rech_dicho_tab_trie et signaler (messages) la non égalité du résultat obtenu avec le résultat attendu. 2. Écrivez la fonction qui retourne la position d’insertion éventuelle d’une valeur dans un tableau supposé trié (recherche dichotomique). taille. } *************************************************************************** 2. /* d<pos */ } else { /* x est avant ou en m */ f = m. 2. sizeof(tab)/sizeof(tab[0])). 5.0. 3.0. 0. if (poss != res[i]) { printf("Probleme seq test no %d. poss. res obtenu : %d\n". Prototype : void test_seq_et_dicho_tab_trie(void). if (t[m] < x) { /* x est forcément après m */ d = m. 3.0. Corrigé *************************************************************************** Comme vu en cours. m. double t[]. int n) { int d. 1. 2. ou la place où devrait se trouver x dans le tableau s’il est absent. 4.0}.1. pbd = 0. /* pos <= f */ } } /* d < pos <=f et d+1==f ==> pos = f */ return f. int n). Prototype : int rech_dicho_tab_trie(double x. l’invariant du programme peut être debut < pos ≤ f in. double test_x[] = {0. tab. Écrivez la fonction qui teste les deux fonctions précédentes.0.0. valeur cherchée). Note : La fonction doit retourner la place du premier x dans le tableau s’il est présent.5. tab. for (i=0.0}. 6. Res attendu :%d. posd. 5.10 Tests (*) Exercice 14. 6. Note : La fonction doit créer des données de tests (tableau trié. double t[]. puis pour chaque donnée de test. i<sizeof(test_x)/sizeof(test_x[0]). poss).0.ESIEE IGI-3005 2. 5. i. 1. res[i]. sizeof(tab)/sizeof(tab[0])). /* pos doit être comprise entre 0 (x<=t[0]) et n (x>t[n-1]) */ /* Invariant logique : d < pos <=f */ d = -1. 8 }.++i) { poss = rech_seq_tab_trie(test_x[i]. /* d < pos */ f = n. int res[] = { 0 . Corrigé *************************************************************************** Par exemple : void test_seq_et_dicho_tab_trie() { double tab[] = {1.0. des résultats attendus.9 TP no 3 (deux séances) (corrigé) 2014-2015 Recherche dichotomique dans un tableau trié (**) Exercice 13. f. 5. 2.0. 4.0. double source[]. res[i]. Écrivez la fonction qui copie les n premiers éléments d’un tableau source de réels dans le tableau destination et retourne l’adresse du tableau destination Prototype : double * copie (double destination[]. } } if (pbs+pbd==0) { printf("\n\nTest passe avec succes\n"). } return ret. int n) { /* Attention : ne fonctionne que si * les tableaux ne se recouvrent pas */ int i. i<n . res obtenu : %d\n". } if (poss != res[i]) { printf("Probleme dicho test no %d. ce qui donne : double *copie(double destination[]. Res attendu :%d. pbd+=1. } ou en plus concis : double *copie(double destination[]. } } *************************************************************************** 3 Copie et décalage de tableaux (**) 3.pbs+pbd).1 Copie simple de tableaux (*) Exercice 15.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 pbs+=1. int n) { /* Attention : ne fonctionne que si * les tableaux ne se recouvrent pas */ double *ret = destintation. int n). } else { printf("\n\nTest echoue : %d erreur(s)\n". ++i) { destination[i] = source[i]. for (i=0 . double source[]. while (n--) { *destination++ = *source++. } *************************************************************************** 3. i. Corrigé *************************************************************************** La solution naturelle est basée sur le principe : on parcourt parallèlement les deux tableaux et on copie élément par élément le contenu du tableau source dans le tableau destination. double source[]. posd).2 Copie sécurisée de tableaux (**) –9/25– . } return destination. Écrivez la fonction qui copie de manière sécurisée les n premiers éléments d’un tableau source de réels dans le tableau destination et retourne l’adresse du tableau destination Attention : On devra prendre en compte le fait que les deux tableaux peuvent se recouvrir partiellement.source < 0 ) { for (i=0 . La différence de deux pointeurs de même type donne le nombre d’éléments de ce type situés entre ces deux pointeurs. int n) { /* fonctionne meme si les tableaux se recouvrent */ int i. Or la fonction va écraser succesivement les éléments du tableau qu’elle n’a pas encore copiés. on copie de la fin vers le début — si source est après destination. on copie du début vers la fin Pour tester le positionnement des deux tableaux. ++i) { destination[i] = source[i]. Corrigé *************************************************************************** Dans la solution précédente.-4. Par exemple. Ci-dessous. Ainsi. quel que soit le type de t : &t[5] . i<n . il suffit de les soustraire.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 Exercice 16.&t[5] vaut -2 Ce qui conduit à : double *copie_sec(double destination[]. un extrait de la documentation de memcpy : If the regions overlap. une erreur peut survenir lorsque l’on appelle cette fonction avec deux tableaux se recouvrant. Une solution consiste à tester la position en mémoire de la source par rapport à la destination : — si source est avant destination.5).5. *************************************************************************** –10/25– . if (destination . ce qui conduira au résultat suivant : 8 8 8 8 8 8 alors que l’on aurait voulu obtenir : 8 8 2 103 -4 5 Faire la boucle dans l’autre sens (de la fin vers le début) poserait le même problème pour un décalage vers la gauche. --i) { destination[i] = source[i].8}. i>=0 . the behavior is undefined.&t[3] vaut 2 &t[3] . } Attention : les fontions memcpy (copie de zones mémoires) et strcpy (copie de chaînes de caractères) de la librairie libc ne gèrent pas les recouvrements. double source[]. } } return destination. Prototype : double * copie_sec (double destination[]. double source[]. int n). avec le morceau de programme suivant : double tab[]={8.2./* tentative de decalage droite */ On voudrait décaler d’une position vers la fin de tableau les cinq premiers éléments.tab. copie(&tab[1]. } } else { for (i=n-1 .103. f-d+1). } ou à l’aide de copie_sec : double *decale_droite(double t[]. int f) { copie_sec(t+d-k. int k. int d. Prototype : double *decale_droite (double t[]. ++i) { t[i-k] = t[i]. double *decale_droite(double t[]. Écrivez la fonction qui décale de k éléments vers la gauche les éléments d’un tableau de réels compris entre l’indice d (inclus) et l’indice f (inclus) et retourne l’adresse du tableau. int k.3 TP no 3 (deux séances) (corrigé) 2014-2015 Décalage droite d’un tableau de réels (*) Exercice 17. double *decale_gauche (double t[]. int f). int d. int d. for (i=f . t+d. } return t. f-d+1). int k. int f) { copie_sec(t+d+k. Corrigé *************************************************************************** Attention à l’ordre de copie. t+d. } *************************************************************************** –11/25– . i<=f . i>=d . --i) { t[i+k] = t[i]. int k. Corrigé *************************************************************************** Attention à l’ordre de copie. } int i. return t. int k. int k. int d. } *************************************************************************** 3. ou à l’aide de copie_sec : double *decale_gauche(double t[].ESIEE IGI-3005 3. return t. } return t. int f) { for (i=d . int d.4 Décalage gauche d’un tableau de réels (*) Exercice 18. Écrivez la fonction qui décale de k éléments vers la droite les éléments d’un tableau de réels compris entre l’indice d (inclus) et l’indice f (inclus) et retourne l’adresse du tableau. Prototype : double *decale_gauche (double t[]. int d. int f). int f) { int i. } *************************************************************************** 4. L’appel repete("toto". *************************************************************************** 4. /* indice gauche et droit de parcours */ char c. s[g]=s[d]. s[d]=c. Corrigé *************************************************************************** void repete (char * s.--d . int n) { int i. } return s. Écrivez une fonction qui prend en argument deux chaînes de caractères et retourne 1 si la première chaîne de caractères commence par la seconde et 0 sinon. la renverse sur elle-même ("toto→"otot") et retourne l’adresse de cette chaîne Prototype : char * miroir (char * s).d.++d){ /* on ne fait rien : on se contente de parcourir la chaîne */ } } for (g=0.s[d]!=0.2 Retournement d’une chaîne(*) Exercice 20.s[i]).j. for (i=0. Écrivez une fonction qui prend en argument une chaîne de caractères et l’affiche en répétant chaque caractère n fois Prototype : void * repete (char * s. Corrigé *************************************************************************** Il faut déjà parcourir la chaîne pour accéder à son dernier caractère. char * miroir (char * s) { int g. –12/25– .ESIEE IGI-3005 4 TP no 3 (deux séances) (corrigé) 2014-2015 Les chaînes de caractères 4. ce qui laisserait la chaîne inchangée.j<n. g<d . int n). 3) affichera tttoootttooo . ++g. Puis permuter les couples de caractères symétriques en évitant de le faire deux fois.3 Recherche de motif (1) (**) Exercice 21. Écrivez un programme pour tester cette fonction.s[i]!=0.1 Répétition (*) Exercice 19.--d) { c=s[g]. for (d=0.++i) for (j=0.++j) printf("%c". Écrivez une fonction qui prend en argument une chaîne de caractères. } } return -1.++i) if (chaine1[i]!=chaine2[i]) return 0. Écrivez une fonction qui prend en argument deux chaînes de caractères et retourne la position de la première occurrence de la chaîne2 dans la chaîne1 si elle y est présente et −1 sinon. char * chaine2).chaine2)) { return i.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 Prototype : int debute_par (char * chaine1. Corrigé *************************************************************************** Une boucle contenant un appel à debute_par permettra de détecter la présence de la sous-chaîne. char * chaine2)."ES") → 1 Corrigé *************************************************************************** Il suffit de regarder pour chaque caractère de chaine2 s’il est égal au caractère correspondant de chaine1 . char * chaine2) { int i. } *************************************************************************** 4. int debute_par (char * chaine1.chaine2[i]!='\0'.4 Recherche de motif (2) (**) Exercice 22. char * s). } *************************************************************************** 4. for (i=0. Écrivez une fonction qui recherche dans une chaîne chaque caractère c pour le remplacer par un caractère r et retourne l’adresse de la chaîne. Prototype : char * cherche_remplace (char c. debute_par ("ESIEE". Dès qu’il y a inégalité.++i) { if (debute_par(&chaine1[i]. for (i=0. Note : ce programme renvoie toujours 1 si la chaine2 est vide. int presence (char * chaine1. char r. Corrigé *************************************************************************** C’est un parcours simple avec remplacement lorsque l’on tombe sur le caractère à remplacer : –13/25– . Note : ce programme considère que la chaîne vide débute toute chaîne (retour 0).chaine1[i]!='\0'. return 1. Si on arrive en bout de chaine2 sans avoir détecté d’inégalité. char * chaine2) { int i. on retourne 0 (faux).5 Chercher/remplacer (*) Exercice 23. Prototype : int presence (char * chaine1. Par exemple. on retourne 1 (vrai). return(s). return ((*s==c)?1:0)+compte2(c.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 char * cherche_remplace (char c.acc=0. qui peut contenir le célèbre '0' . Prototype : int compte(char c. for (i=0.int f[]) { int i. Corrigé *************************************************************************** C’est un parcours simple avec incrémentation dans le tableau du compteur indicé par le caractère courant.s[i]!='\0'. char r. char * s) { int i. for (i=0.++i) if (s[i]==c) ++acc.++i) ++f[(unsigned char)t[i]].++i) if (s[i]==c) s[i]=r.int freq[]). Écrivez une fonction qui compte le nombre d’occurrences d’un caractère c dans une chaîne s. char * s) { int i. return f.i<n. for (i=0. remplit un tableau d’entiers avec les fréquences des 256 caractères ASCII et retourne l’adresse de ce tableau. for (i=0. La fonction pourra être récursive. char * s).s+1).7 Fréquence (2) (**) Exercice 25.s[i]!='\0'. } *************************************************************************** –14/25– . int n . } *************************************************************************** 4. int n . int *frequence (char t[].i<256. Écrivez un programme pour tester cette fonction. Attention : on parle ici de tableau de n caractères.6 Fréquence (1) (**) Exercice 24. Prototype : int * frequence (char t[]. char * s) { if (*s=='\0') /* s[0] == '\0' */ return 0. return(acc).++i) f[i]=0. Corrigé *************************************************************************** C’est encore un accumulateur : int compte (char c. Écrivez une fonction qui prend en argument un tableau de n char . } *************************************************************************** 4. } Une fonction récursive peut être écrite selon le principe suivant : int compte2 (char c. on multiplie par 10 la valeur accumulée et on ajoute la valeur du chiffre. on accumule dans un résultat le nombre représenté selon le principe suivant : pour chaque chiffre. éventuellement précédée d’une caractère '-' ou '+' . } for(. Réfléchissez au problème que posent les ligatures (æ. De plus. Prototype : char * majuscule (char * s). if (s[i]=='+') ++i. À l’ESIEE. –15/25– . Il y a trop bien réussi. ++i. Elles permettent également la conversion d’une chaîne exprimant un nombre en base 8 (commençant par un 0 ) ou en base 16 (commençant par 0x ou 0X ). Corrigé *************************************************************************** Une chaîne représentant un entier est composée d’une suite de caractères chiffres (compris entre '0' et '9' ). Écrivez une fonction qui prend en argument une chaîne de caractères représentant un entier en décimal et retourne l’entier équivalent ("123" → 123) Note : on supposera que la chaîne est correcte et représente bien un entier. Prototype : int chaine_vers_entier (char * s). Corrigé *************************************************************************** Cet exercice (et les suivants qui s’en servent) avait pour but de vous sensibiliser aux problèmes de l’encodage das caractères selon les plate-formes et les langues.8 TP no 3 (deux séances) (corrigé) 2014-2015 Conversion chaîne de caractères en entier (**) Exercice 26. signe=1. S’il y a un signe. on le mémorise sous le forme d’une variable valant -1 ou +1. sur une même machine. on retourne le résultat multiplé par le signe. Écrivez une fonction qui prend en argument une chaîne de caractères. int chaine_vers_entier (char * s) { int i=0. } Note : c’est ainsi que les fontions du genre atoi (conversion d’une chaîne en int ) de la librairie libc opèrent. *************************************************************************** 5 5. la transforme en majuscules ("toto" → "TOTO") et retourne son adresse On laissera inchangés les caractères non lettre. La valeur entière correspondant à un caractère chiffre est égal à ce caractère moins le caractère '0' . Puis.1 Pour aller plus loin Mise en majuscules (**) Exercice 27. res=0.ESIEE IGI-3005 4.s[i]!='\0'. œ) et proposez une solution. On prendra en compte les caractères accentués ou cédillés en les transformant en leurs majuscules sans accent ou sans cédille.++i) { res=res*10+s[i]-'0'. else if (s[i]=='-') { signe=-1. } return signe*res. l’encodage de l’éditeur de texte et de la console peuvent différer. ( '2'-'0' vaut 2). En fin de calcul. elles interrompent le calcul lorsqu’elles parviennent à un caractère non autorisé et retournent le résultat courant. Pour ceux que cela intéresse. fr/Jean-Francois. } Note : Il existe des fonctions int tolower(int) . et les programmer à l’aide d’un switch .i<='z'. ce qui est pénible et peu efficace. ce qui peut donner comme code pour traiter les minuscules : if ('a'<=c && c<='z') return c-32.html donne une présentation très complète du sujet. int isdigit(int) . en général défini par −1. Prototype : int maj(int c). pour permettre le passage ou le retour des caractères classiques. */ } De plus. /* etc .. ’é’ → ’É’ pour un traitement de texte) int maj(int c) { if (0<=c && c<=255) return TABMAJ[c]. plus EOF (end of file). comme par exemple : static int TABMAJ[256]. La normalisation "æ" → "AE" change le nombre de caractère et nécessite alors un buffer de réception de la chaîne normalisée (qui ne sera pas de même taille que la chaîne initiale). *************************************************************************** –16/25– .s[i]!='\0'. Concernant les lettres accentuéess. cette solution peut être adaptée à plusieurs types de majuscules (’é’ → ’E’ pour un classement alphabétique. } TABMAJ[(unsigned char)'à']='A'.++i) { s[i]=maj((unsigned char)s[i]). mais plus efficace. ce qui évite le magic number 32. déclarées dans ctype. } return s. tout aussi pénible. for (i=0. initialisée une fois pour toutes.++i) { TABMAJ[i]=i+'A'-'a'. Concernant le programme proprement dit (mise en majuscule d’une chaîne de caractères).++i) { TABMAJ[i]=i. Il vaut toutefois mieux écrire : if ('a'<=c && c<='z') return c-'a'+'A'.i<256. return c. } Le cas des ligatures (æ. il faut déjà écrire une fonction utilitaire de majuscule d’un caractère. La fonction majuscule demandée s’écrit alors simplement : char * majuscule (char * s) { int i. œ) est plus délicat.. Ces fonctions faisant référence à une table indicée par les caractères. } for (i='a'.ESIEE IGI-3005 TP no 3 (deux séances) (corrigé) 2014-2015 la page http://pagesperso-systeme. une solution consiste à les lister toutes. Une meilleure solution. il faut transtyper un argument char en unsigned char pour éviter les indices négatifs générant une sortie du tableau. TABMAJ[(unsigned char)'é']='E'. Les caractères lettres non accentuées ont les majuscules précédant de 32 (20 hexa) leurs minuscules correspondantes.Perrot/inalco/cours11/index. for (i=0. etc. consiste à créer un tableau indicé par les caractères. void inittabmaj() { int i.h qui permettent de gérer tout ce qui concerne les lettres non accentuées. La fonction est déclarée avec le type int pour son retour et son paramètre. avec leurs majuscules asscociées.lip6. compare("chat". } return strcpy(s. return (s1[i]<s2[i])?-1:1. 0 si elles sont identiques (mises en majuscules) et 1 si la première est après la seconde. char * s2). 8 → "huit"). char * s) { static char *chiffres[10]={ "zéro".h ).++i) /* ou utiliser strcmp */ if (s1[i]==0) return 0. "chien") → −1 compare("zèbre"."relève") → 0 Prototype : int compare (char * s1.chiffres[n]). Écrivez une fonction qui prend en argument deux chaînes de caractères et retourne -1 si la première (mise en majuscule) est avant la seconde (mise en majuscule) par ordre alphabétique. On supposera que la mémoire allouée pour la chaîne est suffisante.h> char * chiffre_vers_chaine (int n. Prenez en compte les lettres accentuées et les ligatures (bœuf) On pourra utiliser strcmp (déclaré dans string. "sept". "deux". "trois". majuscule(s1). Par exemple. *************************************************************************** –17/25– . "quatre"."éléphant") → 1 compare("corne". Corrigé *************************************************************************** Attention : on suppose ici que l’on dispose d’une fonction majuscule permettant de normaliser une chaîne de caractères. char * s2) { int i. majuscule(s2). Corrigé *************************************************************************** Une table static suffira pour cette fonction.s1[i]==s2[i]. Écrivez une fonction qui prend en argument un nombre de un chiffre et remplit une chaîne avec l’écriture en lettres de ce chiffre(par exemple. "un".2 TP no 3 (deux séances) (corrigé) 2014-2015 Classement alphabétique (***) Exercice 28. "neuf"}."COR") → 1 compare("relevé". char * s). "huit". #include <string. "cinq". "six".ESIEE IGI-3005 5. for(i=0. int compare (char * s1. Prototype : char * chiffre_vers_chaine (int n.3 Des chiffres en lettres (**) Exercice 29. } *************************************************************************** 5. break. return(strcat(buffer."dix").) */ if (nombre<=16) { /* 0 .39 */ case 4 : strcpy(buffer. /* 30 . Corrigé *************************************************************************** Ci-dessous un programme écrit il y a plusieurs années qui semble encore fonctionner. /* 20 .nb_en_lettres(txt. "un"."quatorze".52-59 */ strcat(buffer.49 */ case 5 : strcpy(buffer."treize". Généralisez le programme précédent pour faire afficher les nombres entiers en toutes lettres (par exemple."cinquante"). } if (nombre<=59) { /* 17-59 */ switch(nombre/10) { case 1 : strcpy(buffer. if (nombre==60) /* 60 */ return (buffer)."-")."seize"}.ESIEE IGI-3005 5. break. if (nombre%10==1) /* 21."trente"). /* 50 ."douze". else /* 17-19. –18/25– ."onze".31.41. 40.29 */ case 3 : strcpy(buffer. "quinze".51 */ strcat(buffer."-")."dix". 895 → "huit cent quatre-vingt-quinze"). /* 40 ." et ").16 */ strcpy(buffer.nombre-60))).ex. break. /*61.19 */ case 2 : strcpy(buffer. char txt[128]. #include <stdio." et ").22-29.59 */ } if (nombre%10==0) /* 20. } if (nombre<=79) { /* 60-79 */ strcpy(buffer."vingt"). if (nombre%10==1) strcat(buffer. Prototype : void affiche_en_lettres (int n). /* pour les écritures intermédiaires (le 17 de 77 p.h> /******************************************************** * Calcul et retour de : l'écriture en toutes lettres * * d'un petit nombre entier * * fonctionne pour 0-999 * * les règles d'écriture d'un nombre en lettres sont * * tirées de "Grévisse Le bon usage" (p. trivial */ return(buffer)."six". "cinq". /* 17 . Renseignez-vous sur les règles d’écriture des nombres en français. "trois".nom_simple[nombre%10])) .h> #include <string. "neuf". /* 62-69 72-79 */ return (strcat(buffer."quarante").nom_simple[nombre]).32-39. 50 */ return(buffer)."quatre"."sept". 30.572 & suivantes)* * * ********************************************************/ char* nb_en_lettres(char *buffer. 71*/ else strcat(buffer.4 TP no 3 (deux séances) (corrigé) 2014-2015 Des nombres en lettres (****) Exercice 30."soixante"). break. break.42-49."deux". int nombre) { static char *nom_simple[]={"zéro"."huit". /* en dessous de 17. mn.800. strcat(buffer. /*101-199 201-299 etc */ return(strcat(buffer.nombre-80))).900 */ if (nombre>=200) /* 200. /* mille */ n=(int)(nombre%1000). strcat(buffer. /* millions */ m = (int)((nombre%1000000L)/1000). mais deux cent mille) */ char *nombre_en_lettres(char *buffer.txt).mn. } return("Erreur"). mn. strcat(buffer."cent"). if (md>1) strcat(buffer. } else { strcpy(buffer. } if (mn!=0) { if (md!=0) –19/25– 2014-2015 . n sont des nombres inférieurs à 1000 md.nb_en_lettres(buffer."").ESIEE IGI-3005 } TP no 3 (deux séances) (corrigé) } if (nombre<=99) { /* 80-99 */ strcpy(buffer.700."").700. " milliard").900 */ strcat(buffer.800. } strcat(buffer.300.nombre/100)). m.md). if (nombre%100==0) { /* 100. le s final de l'écriture de m disparait (deux cents. /* unités (<1000) */ strcpy(buffer."s")).m. /* milliards */ mn=(int)((nombre%1000000000L)/1000000L).nb_en_lettres(txt."-").500.600. md=(int)(nombre/1000000000L).200.500.nb_en_lettres(txt. il ne s'écrit pas (mille deux. unsigned long nombre) { int md. if (nombre==80) /* 80 */ return (strcat(buffer.400. return(buffer).4))."s").n. } strcat(buffer. strcat(buffer. pas un mille deux) si m=c80(avec c un chiffre quelconque) ou c00 (avec c>=2). n s'écrivent de la même facon (voir la règle des nombres <1000) m suit la meme règle sauf : si m=1.nb_en_lettres(txt.nb_en_lettres(txt."s"). strcat(buffer. /* nombre = md (milliard(s)) mn (million(s)) m (mille) n 1234567890= 1 234 567 890 */ /* Règle : md.nombre%100))). /* 81-99 */ return (strcat(buffer.300.20)). char txt[80]. if (md!=0) { nb_en_lettres(txt. strcat(buffer."-"). } if (nombre<1000) { /*100-999 */ if (nombre>=200) { /*200-999 */ strcpy(buffer." ").400.600." "). if (m!=0) { if (md!=0 || mn!=0) strcat(buffer.m). if (m%100==80 || m%100==0 && m>100) /* suppression du 's' pour 200000 ou 80000*/ txt[strlen(txt)-1]='\0'. strcat(buffer. "mille"). int test(void) { /* à vérifier : 1) les orthographes des noms simples 0 à 16 et des noms servant à composer des noms complexes Règle 01000 0 zéro 01001 1 un 01002 2 deux 01003 3 trois 01004 4 quatre 01005 5 cinq 01006 6 six 01007 7 sept 01008 8 huit 01009 9 neuf 01010 10 dix 01011 11 onze 01012 12 douze 01013 13 treize 01014 14 quatorze 01015 15 quinze 01016 16 seize 01017 20 vingt 01018 30 trente 01019 40 quarante 01020 50 cinquante 01021 60 soixante 01022 100 cent 01023 1000 mille 01024 1 000 000 million 01025 1 000 000 milliard 2) les rèles pour les nombres entre 17 et 59 02000 Les multiples de 10 s'écrivent seuls (sans . if (m>1) { nb_en_lettres(txt.0).txt). strcat(buffer.txt). /* toujours invariable */ } if (n!=0) { if (md!=0 || mn!=0 || m!=0) strcat(buffer.ou 'et' ou zéro) 02001 Les nombres se terminant par 1 s'écrivent <dizaine>" et un" –20/25– 2014-2015 . nb_en_lettres(txt. if (mn>1) strcat(buffer. strcat(buffer." "). } if (nombre==0) { /* cas particulier de 0 tout seul */ nb_en_lettres(txt.txt).ESIEE IGI-3005 } } TP no 3 (deux séances) (corrigé) strcat(buffer. strcat(buffer. } strcat(buffer." ").mn).txt)."s"). } return buffer. strcat(buffer. " million")." ").n)." "). strcat(buffer. nb_en_lettres(txt. ESIEE IGI-3005 02002 3) les règles 03000 03001 03002 03003 TP no 3 (deux séances) (corrigé) Les autes nombres s'écrivent <dizaine>"-"<unité> pour les nombres de 60 à 79 60 s'écrit "soixante" 61 s'écrit "soixante et un" 71 s'écrit "soixante et onze" Les autres nombres s'écrivent "soixante-"<nom de (nombre-60)> 4) les règles pour les nombres de 80 à 99 04000 80 s'écrit "quatre-vingts" s'il termine le nombre 04001 80 s'écrit "quatre-vingt" s'il ne termine pas le nombre 04002 81 s'écrit "quatre-vingt-un" 04003 91 s'écrit "quatre-vingt-onze" 04004 Les autres nombres s'écrivent "quatre-vingt-"<nom de (nombre-80)> 5) les règles pour les nombres de 100 à 199 05000 100 s'écrit "cent" 05001 Les autres nombres s'écrivent "cent "<nom du mombre-100> 6) les règles pour les nombres de 200 à 999 06000 Les multiples de 100 s'écrivent <nom du chiffre des centaines>" cents" s'ils terminent le nombre 06001 Les multiples de 100 s'écrivent <nom du chiffre des centaines>" cent" s'ils ne terminent le nombre 06002 Les autres nombres s'écrivent <nom du chiffre des centaines> " cent "<nom du nombre modulo 100> 7) les règles pour les nombres de 1000 à 1999 07000 1000 s'écrit "mille" 07001 Les autres nombres s'écrivent "mille "<nom du nombre modulo 1000> 8) les règles pour les nombres de 2000 à 999 999 08000 Les multiples de 1000 s'écrivent <nom du nombres de milliers>" mille" 08001 Les autres nombres s'écrivent <nom du nombre de milliers> " mille "<nom du nombre modulo 1000> 9) les règles pour les nombres de 1 000 000 à 1 999 999 09000 1 000 000 s'écrit "un million" 09001 Les autres nombres s'écrivent "un million "<nom du nombre modulo 1 000 000> 10) les règles pour les nombres de 2 000 000 à 999 999 999 10000 Les multiple de 1 000 000 s'écrivent <nom du nombre de millions>" millions" 10001 Les autres nombres s'écrivent <nom du nombre de millions> " millions "<nom du nombre modulo 1 000 000> 11) les règles pour les nombres de 1 000 000 000 à 1 999 999 999 11000 1 000 000 000 s'écrit "un millard" 11001 Les autres nombres s'écrivent "un millard " <nom du nombre modulo 1 000 000 000> 12) les règles pour les nombres de 2 000 000 000 à 999 999 999 999 12000 Les multiple de 1 000 000 000 s'écrivent <nom du nombre de milliards>" milliards" 12001 Les autres nombres s'écrivent <nom du nombre de milliards> " milliards " –21/25– 2014-2015 . "quatre-vingt-onze millions \ quatre-vingt-un mille quatre-vingts"}. {2.t[i]. do { –22/25– 2014-2015 . {20016015. {1001001100L."mille"}."un milliard un million mille cent"}."soixante millions cinquante-neuf \ mille trente et un"}.buffer).01022 */ {1000000. {1000. "deux milliards trois cent quarante-cinq \ millions six cent soixante-dix-huit mille neuf cents"}.0123."deux"}. 09000 */ {1110000.06001."quatre-vingt-quatre"}. for (i=0. char buffer[1024]. } int main() { unsigned int n.t[i]. /* 12000."quatre-vingts millions soixante \ et onze mille soixante et un"}. {80071061. "quatre milliards"}.TP no 3 (deux séances) (corrigé) ESIEE IGI-3005 */ <nom du nombre modulo 1 000 000 000> struct test { unsigned long n."deux mille cent vingt-trois"}. {91081080.n))!=0) { printf("Problème pour : %lu\nAttendu : <%s>\n\ Obtenu : <%s>\n". {180. return c. {100. char *l. {14013012. /* 12001.c).l."mille cent quatre-vingt-douze"}.06002. {60059031. "un milliard six cents millions"}."un million cent dix mille"}. } t[]={ {0.nombre_en_lettres(buffer. test(). 01003 01004 01024*/ {1000000000. {2123. {4000000000."quatre-vingts"}. {84.l. /*01000 */ {2345678900. /*10001. {80.c=0. "un milliard"}. } printf("%d problème(s) dans les tests inclus\n". char b[1024]."vingt et un"} }."un million"}.++i) if (strcmp(t[i]."cent quatre-vingts"}."cent"}. ++c.i<sizeof(t)/sizeof(t[0]). /* 11001.n.04004.t[i]. 01002 */ {1600000000."vingt millions seize mille quinze"}."quatorze millions treize mille douze"}. int i.08001. {1192."zéro"}. 10000. {21. for(. case NONMOT : if (isalpha(*s)) { etat=MOT. } break. Un parcours de la chaîne. Écrivez une fonction qui compte le nombre de mots dans une chaîne de caractères (la documentation devra définir exactement ce que l’on entend par mot). getchar(). on considérera comme mot toute suite continue de une ou plusieurs lettres. *************************************************************************** –23/25– . } } } return cpt. return 0. printf("%s\n". *************************************************************************** 5.nombre_en_lettres(b. Écrivez un programme pour tester cette fonction. scanf("%d".++s) { switch(etat) { case MOT : if (! isalpha(*s)) etat=NONMOT. #include <ctype.h> #define MOT 1 #define NONMOT 0 int compte_mots (char * s) { int etat=NONMOT.*s!='\0'. Corrigé *************************************************************************** Pour ce programme. avec mémorisation d’état. Prototype : int compte_mots (char * s).ESIEE IGI-3005 } TP no 3 (deux séances) (corrigé) 2014-2015 printf("Entrez un entier positif (0 pour finir) : ").5 Compteur de mots (***) Exercice 31.n)). Lors du parcours de la chaîne. permet d’écrire la fonction. } while (n!=0). int cpt=0. break. ++cpt. deux états sont possibles : — on est dans un mot (état MOT) — on n’est pas dans un mot (état NONMOT) Les transitions d’état sont les suivantes : — si on est dans l’état MOT : — si on rencontre une lettre : on reste dans l’état MOT — si on rencontre un caractère non-lettre : on entre dans l’état NONMOT — si on est dans l’état NONMOT — si on rencontre une lettre : on rentre dans l’état MOT — si on rencontre un caractère non-lettre : on reste dans l’état NONMOT On comptera le nombre de mots en incrémentant une variable à chaque fois que l’on entrera dans l’état MOT.&n). } void affiche_complet(int e[].int n) { int i. } int reines(int n) { int ech[n].c. } printf("]\n"). ").col)) { –24/25– .--i) { if ((l[i]==l[n]) || abs(l[i]-l[n])==n-i) { return 0.++l) { for (c=0. } } return 1.c<n. Huit reines doivent être placées sur un échiquier 8 × 8 sans que deux d’entre elles soient en prise. col=0.%d". Prototype : int huit_reines (void). } printf("\n"). printf("\n[%d".e[i]). } else { if (compatible(ech. c’est à dire sur une même ligne. else printf(".ESIEE IGI-3005 5. int col. for (i=1.h> #define abs(a) (a>=0?a:-(a)) void affiche(int e[]. int n) { int i. /* les huit reines */ #include <stdio. Écrivez une fonction calculant et affichant toutes les solutions au problème des huit reines.6 TP no 3 (deux séances) (corrigé) 2014-2015 Les huit reines (***) Exercice 32. } } int compatible(int l[].s. while (col>=0) { ++ech[col].++i) { printf(". printf("\n\n"). if (ech[col]>=n) { --col. ech[0]=-1. for (l=0.++c) { if (e[c]==l) printf("X ").i<n. même colonne ou même diagonale.int n) { int l.l<n. s=0.e[0]).i>=0. for (i=n-1. Corrigé *************************************************************************** Une solution qui utilise un tableau des hauteurs des reines sur l’échiquier. X . .. .. X .n). .... X X . . .. . . . X . . 1x 1 : 2x 2 : 3x 3 : 1 solutions 0 solutions 0 solutions 4x 4 : 2 solutions . . . reines(i))... .. X . ..i<=8. . . .. . .TP no 3 (deux séances) (corrigé) ESIEE IGI-3005 if (col==n-1) { ++s. affiche_complet(ech. . .. . . . . . X . ... } } else { } } } } return s. . ..... . ... . .. X . . } %10d solution(s) \n". . . } else { ++col.. X .. .. echiquier .. . X X .. fin de l'affichage . echiquier 8x 8 : 92 solutions */ *************************************************************************** –25/25– 2014-2015 . . .i. .. . . . .++i) { printf("echiquier %2dx%2d : i.. .. . . . X . . . . . /* début de l'affichage X echiquier echiquier echiquier .. . . return 0. . . . . X . . X . . . int main() { int i. ech[col]=-1.. for (i=1. X . . } getchar(). . X .