// 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); } 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 à" }; // PRE CONDITION: id > 1 char* toStringRelation(rtype id){ 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)); 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)); if (new == NULL) { fprintf(stderr, " malloc == NULL fonction adjqueue(lst,x) \n"); exit(EXIT_FAILURE); } new->val = x; new->suiv = NULL; if( lst != NULL ){ listeg copy = lst; while(copy->suiv != NULL){ copy = copy->suiv; } copy->suiv = new; return lst; }else return new; } listeg suptete(listeg lst){ listeg deuxieme = lst->suiv; free(lst); return deuxieme; } void *tete(listeg lst){ return lst->val; } int longueur(listeg lst){ int res = 0; if( lst == NULL ) return res; res++; listeg copy = lst; while(copy->suiv != NULL){ copy = copy->suiv; res++; } return res; } bool estvide(listeg lst){ return lst == NULL; } void detruire(listeg lst){ if( estvide(lst) ) return; if(lst->suiv == NULL){ free(lst); 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 " etype ident; // l identifiant associe, p.ex OBJET }*Entite; //3.1 les structures de donnees typedef struct s_sommet{ struct s_node* larcs; Entite x; }*Sommet; typedef struct s_arc{ rtype t; struct s_entite* x; }*Arc; typedef struct s_relations{ listeg listDeRelations; }*Relations; //3.2 les constructeurs Entite creerEntite(char *s, etype e){ Entite newEntity = malloc(sizeof(struct s_entite)); if (newEntity == NULL) { fprintf(stderr, " malloc == NULL fonction creerEntite(s,e) \n"); exit(EXIT_FAILURE); } strcpy(newEntity->nom, s); newEntity->ident = e; return newEntity; } Sommet nouvSommet(Entite e){ 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; } Arc nouvArc(Entite e, rtype type){ 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; } void relationInit(Relations *g){ *g = malloc(sizeof(struct s_relations)); if(*g == NULL){ fprintf(stderr, " malloc == NULL function relationInit(*g) \n"); exit(EXIT_FAILURE); } (*g)->listDeRelations = listegnouv(); } void relationFree(Relations *g){ // 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) // 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){ if (e == NULL || string == NULL) { return 0; } if( strcmp( ((Entite)e)->nom, string ) == 0 ){ return 1; } return 0; } int compSommet(void *s, void *string){ 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){ 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){ g->listDeRelations = adjqueue(g->listDeRelations, nouvSommet(creerEntite(nom, t))); } // 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){ 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)); } //////////////////////////////////////// // 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 static char* etype_string[] = { [PERSONNE] = "personne", [OBJET] = "objet", [ADRESSE] = "adresse", [VILLE] = "ville"}; void affichelg(listeg l, void(*aff)(void *)){ while( l != NULL ){ aff(l->val); l = l->suiv; } } void afficheEntite(void *x){ printf("%s :%s\n", ((Entite)x)->nom, etype_string[ ((Entite)x)->ident] ); } void afficheArc(void *x){ 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(); 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)); 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); affichelg( ((Sommet)(r->listDeRelations->val))->larcs, afficheArc ); printf("\n %s \n", ((Arc)(((Sommet)(r->listDeRelations->val))->larcs->val))->x->nom ); //relationFree(&r); return 0; // 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; }