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[] = {

Abdul-Malik Elmurzaev
committed
[0] = "omega", [1] = "inconnue",

Abdul-Malik Elmurzaev
committed
[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;
#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;
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 resultat = listegnouv();

Abdul-Malik Elmurzaev
committed
int i=0;
while(lst != NULL){

Abdul-Malik Elmurzaev
committed
if( comp(lst->val, x)==0 ){
resultat = adjqueue(resultat, lst->val);

Abdul-Malik Elmurzaev
committed
i++;
lst = lst->suiv;

Abdul-Malik Elmurzaev
committed
printf(" %d \n", i);
return resultat;
}
////////////////////////////////////////
// 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;
//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
listeg tete = (*g)->listDeRelations;
while( tete != NULL ){
free( ((Sommet)(tete->val))->x );

Abdul-Malik Elmurzaev
committed
listeg LarcsDuSommet = ((Sommet)(tete->val))->larcs;
listeg LarcTete = LarcsDuSommet; // la tete de larcs la liste listeg du sommet

Abdul-Malik Elmurzaev
committed
while( LarcsDuSommet != NULL ){
free( ((Arc)( LarcsDuSommet->val ))->x );
((Arc)( LarcsDuSommet->val ))->x = NULL;

Abdul-Malik Elmurzaev
committed
free( ((Arc)( LarcsDuSommet->val )) );
LarcsDuSommet->val = NULL;

Abdul-Malik Elmurzaev
committed
LarcsDuSommet = LarcsDuSommet->suiv;
}
detruire(LarcTete);
free( ((Sommet)(tete->val)) );
tete->val = NULL;

Abdul-Malik Elmurzaev
committed
tete = tete->suiv;
}
detruire( (*g)->listDeRelations );
(*g)->listDeRelations = NULL;

Abdul-Malik Elmurzaev
committed
free(*g);
*g = NULL;
}
//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
listeg copy = g->listDeRelations;
while(copy != NULL){

Abdul-Malik Elmurzaev
committed
if( ((Sommet)(copy->val))->x->nom == nom ){
printf("check \n");

Abdul-Malik Elmurzaev
committed
return;

Abdul-Malik Elmurzaev
committed
}

Abdul-Malik Elmurzaev
committed
copy = copy->suiv;
}

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;
}

Abdul-Malik Elmurzaev
committed
listeg copyLarcs = ((Sommet)(g->listDeRelations->val))->larcs;
while( copyLarcs != NULL ){
if( ((Arc)(copyLarcs))->x->nom == nom2 ){
((Arc)(copyLarcs))->t = id;
return;
}
copyLarcs = copyLarcs->suiv;
}
sommet1->larcs = adjqueue(sommet1->larcs, (Arc)nouvArc(creerEntite(sommet2->x->nom, sommet2->x->ident), id));

Abdul-Malik Elmurzaev
committed
sommet2->larcs = adjqueue(sommet2->larcs, (Arc)nouvArc(creerEntite(sommet1->x->nom, sommet1->x->ident), id));
}
////////////////////////////////////////
// Exercice 4: Explorer les relations entre personnes
// 4.1 listes de relations
listeg en_relation(Relations g, char *x){

Abdul-Malik Elmurzaev
committed
listeg res = listegnouv();

Abdul-Malik Elmurzaev
committed
listeg copyTete = g->listDeRelations;
while(copyTete != NULL){
if( strcmp( ((Sommet)(copyTete->val))->x->nom, x ) == 0 ){
return ((Sommet)(copyTete->val))->larcs;

Abdul-Malik Elmurzaev
committed
}

Abdul-Malik Elmurzaev
committed
copyTete = copyTete->suiv;

Abdul-Malik Elmurzaev
committed
}
return res;
listeg chemin2(Relations g, char *x, char *y){ // on renvoit une LISTE D ENTITES
listeg LarcsOfX = en_relation(g, x);
listeg LarcsOfY = en_relation(g, y);
listeg XEntites = listegnouv(); // on va stocker toutes les entites en relation avec x et y
listeg YEntites = listegnouv();
listeg RES = listegnouv(); // puis mettres dans RES les entités en commun sauf x et y
listeg LarcsOfX_copy = LarcsOfX;
listeg LarcsOfY_copy = LarcsOfY;
while(LarcsOfX_copy != NULL){
XEntites = adjqueue(XEntites, ((Arc)(LarcsOfX_copy->val))->x );
LarcsOfX_copy = LarcsOfX_copy->suiv;
}
while(LarcsOfY_copy != NULL){
YEntites = adjqueue(YEntites, ((Arc)(LarcsOfY_copy->val))->x );
LarcsOfY_copy = LarcsOfY_copy->suiv;
}
listeg XEntites_copy = XEntites;
listeg YEntites_copy = YEntites;

Abdul-Malik Elmurzaev
committed
while(XEntites_copy != NULL){

Abdul-Malik Elmurzaev
committed
YEntites_copy = YEntites;
while(YEntites_copy != NULL){

Abdul-Malik Elmurzaev
committed
//printf("a \n");
if( compEntite(XEntites_copy->val, ((Entite)(YEntites_copy->val))->nom) ){

Abdul-Malik Elmurzaev
committed
RES = adjqueue(RES, XEntites_copy->val );
printf("check \n");

Abdul-Malik Elmurzaev
committed
//printf(" ___________ %s \n", ((Entite)(RES->val))->nom );
}
YEntites_copy = YEntites_copy->suiv;
}
XEntites_copy = XEntites_copy->suiv;
}

Abdul-Malik Elmurzaev
committed
detruire(XEntites);
detruire(YEntites);
return RES;
}
// 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 0;
// 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;
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[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
// 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");
return 0; /////
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
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;
}