Newer
Older
// relations.c : definit le point d'entree pour l'application .
//
typedef int bool;
#define false 0
#define true -1
#include "stdlib.h"
#include "memory.h"
#include "stdio.h"
#include "string.h"
////////////////////////////////////////
// Exercice 1: Classement des Relations
typedef enum{
FRERE = 2, COUSIN, PARENT, ONCLE, EPOUX, AMI, VIT, CONNAIT,
CHEF, COLLEGUE, LOCATAIRE, TRAVAILLE, PROPRIETAIRE, SITUE, DECOUVERT
}rtype;
bool est_lien_parente(rtype id){
return (id == FRERE || id == COUSIN || id == PARENT || id == ONCLE);
bool est_lien_professionel(rtype id){
return (id == CHEF || id == COLLEGUE);
}
bool est_lien_connaissance(rtype id){
return (id == EPOUX || id == AMI || id == CONNAIT || id == VIT);

Abdul-Malik Elmurzaev
committed
static char* RelationsTable[] = {
[2] = "frère ou soeur de", [3] = "cousin ou cousine de", [4] = "père ou mère",
[5] = "oncle ou tante de", [6] = "époux ou épouse de", [7] = "ami de",
[8] = "vit avec", [9] = "connait", [10] = "supérieur de",
[11] = "collègue de", [12] = "locataire de", [13] = "travaille à",
[14] = "propriétaire de", [15] = "situé à", [16] = "découvert à"
};

Abdul-Malik Elmurzaev
committed
// PRE CONDITION: id > 1

Abdul-Malik Elmurzaev
committed
return RelationsTable[id];
}
////////////////////////////////////////
// Exercice 2: Liste de pointeurs
typedef struct s_node{
void *val; // pointeur vers objet quelconque
struct s_node *suiv;
}*listeg;
listeg listegnouv(){
return NULL;
}
listeg adjtete(listeg lst, void *x){
listeg new = malloc(sizeof(struct s_node));

Abdul-Malik Elmurzaev
committed
if (new == NULL) {
fprintf(stderr, " malloc == NULL fonction adjtete(lst,x) \n");
exit(EXIT_FAILURE);
}
new->val = x;
new->suiv = lst;
return new;
}
listeg adjqueue(listeg lst, void *x){
listeg new = malloc(sizeof(struct s_node));

Abdul-Malik Elmurzaev
committed
if (new == NULL) {
fprintf(stderr, " malloc == NULL fonction adjqueue(lst,x) \n");
exit(EXIT_FAILURE);
}
new->val = x;
new->suiv = NULL;

Abdul-Malik Elmurzaev
committed
if( lst != NULL ){
listeg copy = lst;
while(copy->suiv != NULL){
copy = copy->suiv;
}
copy->suiv = new;
return lst;
}else

Abdul-Malik Elmurzaev
committed
return new;
listeg deuxieme = lst->suiv;
free(lst);
return deuxieme;
return lst->val;
int res = 0;
if( lst == NULL )
return res;
res++;
listeg copy = lst;
while(copy->suiv != NULL){
copy = copy->suiv;
res++;
}
return res;
return lst == NULL;
if( estvide(lst) )
return;
if(lst->suiv == NULL){
free(lst);

Abdul-Malik Elmurzaev
committed
return;
}
listeg copy = lst;
while(copy != NULL){
copy = copy->suiv;
free(lst);
lst = copy;
}
listeg rech(listeg lst, void *x, int(*comp)(void *, void *)){
listeg copy = lst;
while(copy != NULL){
if( comp(x, copy->val) ){
return lst;
}else{
copy = copy->suiv;
}
}
return NULL;
}
////////////////////////////////////////
// Exercice 3: Construction du graphe
#define LONG_NOM_MAX 64
typedef enum{
PERSONNE=1, OBJET, ADRESSE, VILLE
}etype;
typedef struct s_entite{
char nom[LONG_NOM_MAX]; // le nom de l entite p.ex " Peugeot 106 "

Abdul-Malik Elmurzaev
committed
etype ident; // l identifiant associe, p.ex OBJET

Abdul-Malik Elmurzaev
committed
//3.1 les structures de donnees
struct s_node* larcs;
Entite x;

Abdul-Malik Elmurzaev
committed
rtype t;
struct s_entite* x;
}*Arc;
typedef struct s_relations{

Abdul-Malik Elmurzaev
committed
listeg listDeRelations;
}*Relations;
//3.2 les constructeurs
Entite creerEntite(char *s, etype e){
Entite newEntity = malloc(sizeof(struct s_entite));

Abdul-Malik Elmurzaev
committed
if (newEntity == NULL) {
fprintf(stderr, " malloc == NULL fonction creerEntite(s,e) \n");
exit(EXIT_FAILURE);
}
strcpy(newEntity->nom, s);
newEntity->ident = e;
return newEntity;

Abdul-Malik Elmurzaev
committed
if(e == NULL){
fprintf(stderr, " nouvSommet(e) erreur e == NULL ici fonction nouvSommet(e) \n");
exit(EXIT_FAILURE);
}
Sommet s = malloc(sizeof(struct s_sommet));
if (s == NULL) {
fprintf(stderr, " malloc == NULL fonction nouvSommet(e) \n");
exit(EXIT_FAILURE);
}
s->x = e;
s->larcs = listegnouv();
return s;

Abdul-Malik Elmurzaev
committed
if(e == NULL){
fprintf(stderr, " nouvSommet(e) erreur e == NULL ici fonction nouvArc(e,type) \n");
exit(EXIT_FAILURE);
}
Arc bow = malloc(sizeof(struct s_arc));
if (bow == NULL) {
fprintf(stderr, " malloc == NULL fonction nouvArc(e,type) \n");
exit(EXIT_FAILURE);
}
bow->t = type;
bow->x = e;
return bow;

Abdul-Malik Elmurzaev
committed
*g = malloc(sizeof(struct s_relations));
if(*g == NULL){
fprintf(stderr, " malloc == NULL function relationInit(*g) \n");
exit(EXIT_FAILURE);
}
(*g)->listDeRelations = listegnouv();

Abdul-Malik Elmurzaev
committed
// il faut free g, il faut aussi free g->listeDeRelations (qui est un listeg),
// 999 et il faut free g->listeDeRelations->val (qui est un sommet),
// 999 et il faut free g->listeDeRelations->val->x (qui est une entite),
// 999 et il faut free g->listeDeRelations->val->larcs (qui est un listeg),
// 999 et il faut free tous les g->listeDeRelations->val->larcs->val (qui sont des arcs),
// 999 et il faut free tous les g->listeDeRelations->val->larcs->val->x (qui sont des entites)

Abdul-Malik Elmurzaev
committed
// commençont par tous les g->listeDeRelations->val->larcs->val->x et du val qui va avec
free( ((Sommet)((*g)->listDeRelations->val))->x );
listeg tete = (*g)->listDeRelations;
printf("check 0 \n");
while( tete != NULL ){
listeg LarcsDuSommet = ((Sommet)(tete->val))->larcs;
listeg LarcTete = LarcsDuSommet;
while( LarcsDuSommet != NULL ){
printf("check 1 \n");
free( ((Arc)( LarcsDuSommet->val ))->x );
printf("check 2 \n");
free( ((Arc)( LarcsDuSommet->val )) );
LarcsDuSommet = LarcsDuSommet->suiv;
}
printf("check 3 \n");
detruire(LarcTete);
printf("check 4 \n");
free( ((Sommet)(tete->val)) );
printf("check 5 \n");
tete = tete->suiv;
}
detruire( (*g)->listDeRelations );
free(*g);
}
//3.3 les comparaisons
int compEntite(void *e, void *string){

Abdul-Malik Elmurzaev
committed
if (e == NULL || string == NULL) {
return 0;
}
if( strcmp( ((Entite)e)->nom, string ) == 0 ){
return 1;
}
return 0;
}
int compSommet(void *s, void *string){

Abdul-Malik Elmurzaev
committed
if (s == NULL || string == NULL) {
return 0;
}
if( strcmp( ((Sommet)s)->x->nom, string ) == 0 ){
return 1;
}
return 0;
}
int compArc(void *a, void *string){

Abdul-Malik Elmurzaev
committed
if (a == NULL || string == NULL) {
return 0;
}
if( strcmp( ((Arc)a)->x->nom, string ) == 0 ){
return 1;
}
return 0;
}
//3.4 ajout d'entites et de relations
void adjEntite(Relations g, char *nom, etype t){

Abdul-Malik Elmurzaev
committed
g->listDeRelations = adjqueue(g->listDeRelations, nouvSommet(creerEntite(nom, t)));

Abdul-Malik Elmurzaev
committed
// PRE CONDITION: id doit etre coherent avec les types des sommets correspondants a x et y
// p.ex si x est de type OBJET, id ne peut pas etre une relation de parente
// PRE CONDITION: strcmp(nom1,nom2)!=0
void adjRelation(Relations g, char *nom1, char *nom2, rtype id){

Abdul-Malik Elmurzaev
committed
Sommet sommet1 = NULL;
Sommet sommet2 = NULL;
Entite deuxiemeEntite = NULL;
listeg copy = g->listDeRelations;
while( copy != NULL ){
if( strcmp(((Sommet)(copy->val))->x->nom, nom1)==0 ){
sommet1 = (Sommet)(copy->val);
}
if( strcmp(((Sommet)(copy->val))->x->nom, nom2)==0 ){
sommet2 = (Sommet)(copy->val);
}
copy = copy->suiv;
}
sommet1->larcs = adjqueue(sommet1->larcs, (Arc)nouvArc(sommet2->x, id));
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
}
////////////////////////////////////////
// Exercice 4: Explorer les relations entre personnes
// 4.1 listes de relations
listeg en_relation(Relations g, char *x){
return NULL;
}
listeg chemin2(Relations g, char *x, char *y){
return NULL;
}
// 4.2 verifier un lien de parente
// PRE CONDITION: strcmp(x,y)!=0
bool ont_lien_parente(Relations g, char *x, char *y){
return false;
}
// 4.3 tester connaissances
// PRE CONDITION: les sommets correspondants � x et y sont de type PERSONNE
// PRE CONDITION: strcmp(x,y)!=0
bool se_connaissent(Relations g, char *x, char *y){
return false;
}
// PRE CONDITION: les sommets correspondants � x et y sont de type PERSONNE
// PRE CONDITION: strcmp(x,y)!=0
bool se_connaissent_proba(Relations g, char *x, char *y){
return false;
}
// PRE CONDITION: les sommets correspondants � x et y sont de type PERSONNE
// PRE CONDITION: strcmp(x,y)!=0
bool se_connaissent_peutetre(Relations g, char *x, char *y){
return false;
}
////////////////////////////////////////
// Exercice 5: Affichages

Abdul-Malik Elmurzaev
committed
static char* etype_string[] = { [PERSONNE] = "personne", [OBJET] = "objet", [ADRESSE] = "adresse",
[VILLE] = "ville"};
void affichelg(listeg l, void(*aff)(void *)){

Abdul-Malik Elmurzaev
committed
while( l != NULL ){
aff(l->val);
l = l->suiv;
}
}

Abdul-Malik Elmurzaev
committed
printf("%s :%s\n", ((Entite)x)->nom, etype_string[ ((Entite)x)->ident] );

Abdul-Malik Elmurzaev
committed
printf(" --%s-->", toStringRelation(((Arc)x)->t));
afficheEntite( ((Arc)(x))->x );
}
////////////////////////////////////////
// Exercice 6: Parcours
void affiche_degre_relations(Relations r, char *x){
}
int main(){
int i,j;
printf("test toStringRelation(16) == %s \n", toStringRelation(16));
printf("test est_lien_parente : %d %d %d \n",est_lien_parente(COUSIN),est_lien_parente(LOCATAIRE),
est_lien_parente(EPOUX));
printf("test est_lien_professionel : %d %d %d \n", est_lien_professionel(LOCATAIRE),
est_lien_professionel(CHEF), est_lien_professionel(COLLEGUE));
printf("test est_lien_connaissance : %d %d %d \n", est_lien_connaissance(AMI),
est_lien_connaissance(CONNAIT), est_lien_connaissance(COLLEGUE));
listeg liste = listegnouv();

Abdul-Malik Elmurzaev
committed
int x5 = 5, x4 = 4, x19 = 19, x3 = 3, x33 = 33;
int *px5, *px4, *px19, *px3, *px33;
px5 = &x5; px4 = &x4; px19 = &x19; px3 = &x3; px33 = &x33;
int x0 = 0; int* px0 = &x0;
liste = adjqueue(liste, &px5);
liste = adjtete(liste, &px4);
liste = adjqueue(liste, &px19);
liste = adjtete(liste, &px3);
liste = adjqueue(liste, &px33);
liste = adjtete(liste, &px0);
liste = suptete(liste);
listeg copy = liste;
for(int i=0; i<4; i++){
printf("liste->val == %d \n", **(int**)copy->val);
copy = copy->suiv;
}
printf("tete(liste) == %d \n", **(int**)tete(liste));

Abdul-Malik Elmurzaev
committed
detruire(liste);
Relations r; relationInit(&r);
// ajouter les entites de l'exemple
char *tabe[] ={"KARL","LUDOVIC","CELINE","CHLOE","GILDAS","CEDRIC","SEVERINE",
"PEUGEOT 106" ,"1, RUE DE LA RUE","STRASBOURG" };
for (i = 0; i < 7; i++)
adjEntite(r, tabe[i], PERSONNE);
adjEntite(r, tabe[7], OBJET);
adjEntite(r, tabe[8], ADRESSE);
adjEntite(r, tabe[9], VILLE);
// ajouter les relations de l'exemple
adjRelation(r, tabe[0], tabe[1], FRERE);
adjRelation(r, tabe[0], tabe[2], AMI);
adjRelation(r, tabe[0], tabe[3], CONNAIT);
adjRelation(r, tabe[0], tabe[5], COUSIN);
adjRelation(r, tabe[0], tabe[7], PROPRIETAIRE);
adjRelation(r, tabe[0], tabe[8], PROPRIETAIRE);
adjRelation(r, tabe[3], tabe[4], VIT);
adjRelation(r, tabe[5], tabe[6], EPOUX);
adjRelation(r, tabe[5], tabe[8], LOCATAIRE);
adjRelation(r, tabe[7], tabe[8], DECOUVERT);
adjRelation(r, tabe[8], tabe[9], SITUE);

Abdul-Malik Elmurzaev
committed
affichelg( ((Sommet)(r->listDeRelations->val))->larcs, afficheArc );
printf("\n %s \n", ((Arc)(((Sommet)(r->listDeRelations->val))->larcs->val))->x->nom );
//relationFree(&r);
return 0;
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
// explorer les relations
printf("%s est en relation avec:\n", tabe[0]);
affichelg(en_relation(r, tabe[0]),afficheArc);
printf("\n");
for (i = 0; i < 7; i++) for (j = i + 1; j < 10; j++)
{
printf("<%s> et <%s> ont les relations communes:\n", tabe[i], tabe[j]);
listeg ch = chemin2(r, tabe[i], tabe[j]);
affichelg(ch, afficheEntite);
printf("\n");
detruire(ch);
}
printf("\n\n");
for (i = 0; i < 10; i++) for (j = i + 1; j < 10; j++)
{
printf("<%s> et <%s> ont lien de parente: %s\n",
tabe[i], tabe[j], ont_lien_parente(r, tabe[i], tabe[j]) ? "vrai" : "faux");
}
printf("\n");
for (i = 0; i < 7; i++)
{
for (j = i + 1; j < 7; j++)
{
printf("<%s> et <%s> se connaissent: %s\n",
tabe[i], tabe[j], se_connaissent(r, tabe[i], tabe[j]) ? "vrai" : "faux");
printf("<%s> et <%s> se connaissent tres probablement: %s\n",
tabe[i], tabe[j], se_connaissent_proba(r, tabe[i], tabe[j]) ? "vrai" : "faux");
printf("<%s> et <%s> se connaissent peut etre: %s\n",
tabe[i], tabe[j], se_connaissent_peutetre(r, tabe[i], tabe[j]) ? "vrai" : "faux");
}
printf("\n");
}
affiche_degre_relations(r, tabe[3]);
relationFree(&r);
printf("\nPRESS RETURN\n");
char buff[64]; fscanf(stdin, "%s", buff);
return 0;
}