Examen de programmation et algorithmes

Transcription

Examen de programmation et algorithmes
Année 2011-2012
1ère année PET
Durée : 2h
Examen de programmation et algorithmes
Tous documents interdits, calculatrice interdite
Remarques
• Les questions sont indépendantes dans une large mesure. Vous pouvez utiliser les fonctions écrites dans les questions
précédentes sans les réécrire.
• Si une question vous semble pouvoir être interprétée de plusieurs manières, indiquez celle que vous avez choisie.
• Toutes les fonctions et programmes doivent être rédigés en langage C.
• Le barème est indicatif
Question 1 Equation du second degré : 2+1 points
• Ecrire une fonction qui résout dans R l’équation du second degré a x2 + bx + c = 0. La fonction prend
en paramètres les trois réels a,b,c, ainsi que 2 réels x1 et x2 représentant les solutions. Cette
fonction retourne de plus la valeur 2 si il existe 2 solutions réelles, 1 s’il n’existe qu’une seule
solution et 0 si il n’existe pas de solutions réelles. Le paramètre a est supposé non nul.
Pour résoudre une équation du second degré, il faut calculer son discriminant delta=b*b-4*a*c.
S’il est positif, il y a deux solutions réelles : x1=(-b+sqrt(delta))/(2*a) et x2=(-b-sqrt(delta))/(2*a)
S’il est nul, il y une solution double : x1=x2=-b/(2*a)
S’il est négatif, il n’y a pas de solutions réelles
•
Ecrire un programme qui lit les 3 réels a,b,c au clavier, résout l’équation du second degré en
utilisant la fonction ci dessus, et affiche ensuite les solutions si elles existent.
Question 2 Tableaux et pointeurs : 1+1+1 points
• Ecrire un programme qui réalise les actions suivantes :
o création d'un tableau t1 de 10 réels double précision
o allocation dynamique d'un tableau t2 de 10 réels double précision
o initialisation par une valeur aléatoire des éléments de t1
o Copie des éléments de t1 dans t2.
• Ecrire la fonction double produit1(double tab[], int nb) ) qui retourne le produit
des éléments du tableau tab de nb réels double précision, en utilisant des indices entiers pour
parcourir le tableau.
• Ecrire la fonction double produit2(double tab[], int nb) ) qui retourne le produit
des éléments du tableau tab de nb réels double précision, en utilisant des indices pointeurs pour
parcourir le tableau. Aucun indice entier n’est autorisé.
Question 3 Fonctions et paramètres : 1+1+1 points
• Ecrire une fonction qui échange deux réels double précision.
• En utilisant la fonction précédente, écrire une fonction qui effectue une permutation circulaire de
trois réels double précision.
• En utilisant les fonctions précédentes, écrire un programme qui :
o lit 3 réels au clavier
o affiche ces 3 réels
o échange les 2 premiers réels
o affiche à nouveau ces deux réels
o permute les 3 réels
o affiche ces 3 réels
- 1/4-
Question 4 Traitement d’images : 2+1+2+1+2+2+1 points
• Ecrire la fonction unsigned
char**
alloue_image(int
nblignes,
int
nbcolonnes) qui alloue dynamiquement une image, tableau 2D d’octets (unsigned char).
•
L’histogramme est un tableau d’entiers t dont chaque élément t[i] est le nombre de fois
qu’apparaît la valeur i dans l’image. La dimension du tableau d’entiers t est le nombre de valeurs
possibles de l’image. Un pixel prend des valeurs comprises entre 0 et 255. Ecrire la fonction int*
histo_image(unsigned char** im, int nblignes, int nbcolonnes) qui
retourne l’histogramme et réalise les opérations suivantes :
o Allocation dynamique de l’histogramme (tableau d’entiers)
o Calcul de l’histogramme de l’image im.
•
Eroder consiste à parcourir toute l’image et à trouver le minimum du voisinage du pixel (les 8 pixels
voisins) contient au moins un point qui n’est pas un trou. On remplace le pixel par ce minimum.
E(x, y) = min(I(x + dx, y + dy)
(dx,dy )∈[−1,1]×[−1,1]
Ecrire la fonction unsigned char** erode_image(unsigned char** im, int
nblignes, int nbcolonnes) qui alloue dynamiquement une image, calcule l’erosion de
l’image im et retourne cette image. On ne traitera pas les pixels au bord de l’image.
• Le patch P(x,y), de dimension n, situé en x,y est la partie de l’image dont les coordonnées
sont [x-n,x+n] x [y-n,y+n]. La distance entre le patch P(x,y) et le patch P(u,v) est l’écart
quadratique moyen i.e.
n
n
2
d 2 (P(x, y),P(u,v)) = 1 k * ∑ ∑ ( P(x + dx, y + dy) − P(u + dx,v + dy )
dx =−n dy =−n
où k est le nombre de pixels dans l'image
Ecrire une fonction double distance(unsigned char** image, int x, int y, int u,
int v, int n, int nblignes, int nbcolonnes) qui retourne la distance entre 2 patchs de
taille n. Attention, il faut exclure les points qui seraient en dehors de l'image.
•
On souhaite connaître pour chaque point x,y de l'image, où se trouve le patch P(u,v) le plus
ressemblant et quelle est sa distance au patch P(x,y), en excluant bien sur la position x,y elle-même.
o Définir une structure ST permettant de stocker 2 coordonnées entières et une distance réelle.
o Définir le tableau ppv permettant de stocker position et distance du meilleur patch.
o Ecrire une fonction ST meilleurpatch(unsigned char** image, int x,
int y, int n, int nblignes, int nbcolonnes)qui retourne la position et la
distance du patch le plus ressemblant à P(x,y), patch situé en x,y, de taille n.
o Ecrire une fonction qui calcule le tableau 2D ppv contenant la position et distance du
meilleur patch de chaque point de l'image.
•
Les images sont contenues dans un fichier texte. La première ligne contient le nombre de lignes et le
nombre de colonnes. Ensuite, on trouve les valeurs de l’image. Ecrire la fonction unsigned
char** lecture_image(char* nom_fichier, int* adr_nblignes, int*
adr_nbcolonnes) qui retourne l’image créée et réalise les opérations suivantes :
o Ouverture du fichier nom_fichier
o Lecture du nombre de lignes et de colonnes dans ce fichier
o Allocation dynamique de l’image
o Lecture dans le fichier des valeurs de l’image im.
•
Ecrire le programme qui réalise les opérations suivantes :
o Lecture de l'image im1 dans fichier ima1.pgm
o Calcul de l'histogramme de cette image
o Affichage des valeurs de l'histogramme
o Erosion de l’image im1 pour obtenir l'image im2
- 2/4-
Résumé de la syntaxe du langage C
Structure d’un programme
int main() {
déclaration des variables ;
instructions ;
}
Déclaration des variables : type_de_variable nom_de_variables ;
Exemples : int i ; double x ; char c ; char s1[256] ; int* p1 ; double* p2 ;
Entrées :
Sorties:
scanf("%d ",&i) ; scanf("%lf", &x) ; scanf("%c", &c) ; scanf("%s", s1) ;
printf("%d ",i) ; printf("%lf", x) ; printf("%c", c) ; printf("%s", s1) ;
Boucle POUR:
for (<initialisation>; <test_continuation>; <incrementation>) {
<instructions_a_repeter> ;
}
Exemple : for (i=0 ; i< 100 ; i++) { t1[i] = 2*i ; }
Boucle TANTQUE:
<initialisation>
while (<test_continuation>) {
<instructions_a_repeter> ;
<incrementation> ;
}
Exemple : while ( i< 100 ) { t1[i] = 2*i ; i= i+1 ;}
Boucle FAIRE..TANTQUE:
<initialisation>
do {
<instructions_a_repeter> ;
<incrementation> ;
} while (<test_continuation>) ;
Exemple : do { t1[i] = 2*i ; i= i+1 ;} while ( i< 100 ) ;
Instruction condionnelle: if (test) { instructions_si_test_est_vrai ; } else { instructions_si_test_est_faux; }
Exemple : if (a !=0) { c = b/a ; } else { printf("La division est interdite\n") ; }
Pointeurs et adresse: l’opérateur & permet d’obtenir l’adresse d’une variable, l’opérateur * permet
d’obtenir la valeur située à une adresse; Exemple :
int i ;
int* p =NULL; /* p est une variable pointeur contenant une adresse*/
p=&i ; /* p contient maintenant l’adresse de i*/
*p = 9 ; /¨On met 9 dans la variable situé à l’adresse donnée par p, ie on met 9 dans i*/
Fonctions : déclaration
type_retourné nom_de_la_fonction(declaration des parametres de la fonction) {
Declaration des variables ;
Instructions de la fonction ;
}
Exemple :
double max( double a, double b) { double c ;
if (a>b) c =a ;
else c=b ;
return c ;
}
- 3/4-
Tableau 1D: déclaration : type_des_elements nom_du_tableau[Nombre d’element] ;
Exemple : int t1[100] ; double x1[256] ;
Le nom du tableau est son adresse
L’adresse d’un élément du tableau s’écrit &t[i] ou t+i
Tableau 2D: déclaration : type_des_elements nom_du_tableau[Nombre_d’element][Nombre d’element] ;
Exemple : int t2d[100] [20]; double x2d[256] [3];
Déclaration d’un type structure : struct nom_de_la_structure { déclarations des champs ; } ;
Déclaration d’une variable de type structuré: struct nom_de_la_structure nom_de_la_variable;
Exemple :
struct complex { double reel ; double imaginaire ; } ; /* Un type complexe*/
struct complex x ; /* x est une variable de type complexe */
Déclaration d’un nouveau type : typedef ancien_type nouveau_type ;
Exemple : typedef struct complex MesComplexes ;
Fichiers :
Declaration d’une variable : FILE* nom_de_variable ;
Ouverture :
FILE* fopen(char* nom_du_fichier_a_ouvrir, char* mode_d’ouverture) ;
Lecture fichier texte :
int fscanf(FILE* variable_fichier, char* format des données a lire, adresses des données) ;
Ecriture fichier texte :
int fprintf(FILE* variable_fichier, char* format des variables a ecrire , variables_a_ecrire) ;
Lecture fichier binaire :
int
fread(void*
adresse_donnees,
variable_fichier_dans lequel on lit) ;
int
taille_d’un_element,
int
nombre_d’element,
FILE*
Ecriture fichier binaire :
int fwrite(void* adresse_donnees,
variable_fichier_dans lequel on ecrit) ;
int
taille_d’un_element,
int
nombre_d’element,
FILE*
Allocation dynamique
Allocation d’un espace :
void* calloc(int nombre_d’element_a_allouer, int taille_d’un_element) ;
Libération mémoire :
void free(void* adresse_de_la_zone_a_liberer) ;
Quelques fonctions sur les chaines de caractères:
Lecture d’une chaine : scanf("%s",mot) : lecture d’une chaine au clavier. Remplace le caractère ‘\n’
(« retour chariot ») par le caractère '\0' (marque de fin de chaine).
Longueur d’une chaine : int strlen(char* mot) : retourne le nombre de caractères de la chaine
Comparaison de 2 chaines : int strcmp(char* s1, char* s2) : retourne une valeur négative si s1<s2, nulle si s1
et s2 sont identiques, et positive si s1 > s2 : c’est l’ordre lexicographique qui est utilisé.
Copie d’une chaine : char* strcpy(char* s1, char* s2) : copie de la chaine s2 dans la chaine s1. La chaine s1
doit comporter suffisamment de place pour contenir la chaine s2.
- 4/4-