From faf8027312567ea68efaf47a3a417221c62f5845 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Fri, 12 Nov 2021 17:15:53 +0100 Subject: [PATCH] CCCCCCCCCCCCCCCC --- C12.c => C12.1.c | 25 ++- C12.2.c | 452 +++++++++++++++++++++++++++++++++++++++++++++++ C12.md | 23 --- CP12.8.c | 48 +++-- CP12.md | 16 +- 5 files changed, 517 insertions(+), 47 deletions(-) rename C12.c => C12.1.c (63%) create mode 100644 C12.2.c delete mode 100644 C12.md diff --git a/C12.c b/C12.1.c similarity index 63% rename from C12.c rename to C12.1.c index e9e9cc3..c1b40af 100644 --- a/C12.c +++ b/C12.1.c @@ -20,19 +20,34 @@ void description(personne* p){ } +int scanfs(char** dest, int length){ + + if(fgets(*dest, length, stdin)==NULL){ + return 1;// Une erreur est survenue lors de la lecture (trop long ?) + } + + // On doit supprimer le retour à la ligne qu'a capturé fgets. + int i; + for(i=0;iinitiales = initiales; p->age = age; diff --git a/C12.2.c b/C12.2.c new file mode 100644 index 0000000..ab9e29a --- /dev/null +++ b/C12.2.c @@ -0,0 +1,452 @@ +#include +#include +#include + +/* 1 */ + +/* +Le graphe représente les objets personnes rencontrés pendant la série. +Chaque case représente le départ d'une flèche vers un autre personnage (ou · pour pas de flèche) qui correspond à : + +``` +-------------- +| 1 | 2 | +------------ +| | 3 | +| nom |-----| +| | 4 | +------------- +| 6 | 5 | +------------- +``` +1. Pointeur vers le père +2. Pointeur vers la mère +3. Chainage des frères et sœurs coté du père +4. Chainage des frères et sœurs coté de la mère +5. Pointeur vers le premier enfant +6. Liste de tous les personnages + + +Le chainage crée une «liste» accessible depuis n'importe lequel des membres + +Pour le pointeur 6, la flèche pointant sur jihair représente le début de la liste. +*/ + +/* 2 */ + +// Le sexe des personnes qui sont parent peut être retrouvé (il suffit de regarder leur premier enfant, si ils en sont le père ou la mère). +// Les autres, on peut dire qu'on s'en fiche, leur sexe sera «défini» au moment ou un couple les contenant aura un enfant. + +/* 3 */ + +// Le chainage général permet de pouvoir lister les personnage, et ainsi de pouvoir par exemple chercher un personnage de par son nom, ou toute autre information stoqué dedans. + +/* 4 */ +// L'avantage de ces listes chainées horizontales est qu'elle sont accessibles simplement depuis n'importe quel membre de la liste. + +/* 5 */ + +struct personnage{ + + char* nom; + struct personnage* pere; + struct personnage* mere; + struct personnage* frereSuivantPapa; + struct personnage* frereSuivantMaman; + struct personnage* premierEnfant; + struct personnage* chaineGlobale; + +}; + +/* 6 */ + +struct personnage* getByName(struct personnage* origin, char* name){ + + while(origin!=NULL && strcmp(name,origin->nom)!=0){ + origin = origin->chaineGlobale; + } + return origin; + +} + +/* 7 */ + +struct personnage* newUnrelated(struct personnage* origin, char* name){ + + struct personnage* dest = (struct personnage*) malloc(sizeof(struct personnage)); + dest->nom = name; + dest->frereSuivantPapa = dest->frereSuivantMaman = dest; + dest->pere = dest->mere = dest->premierEnfant = NULL; + if(origin!=NULL){ + while(origin->chaineGlobale!=NULL)origin = origin->chaineGlobale; + origin->chaineGlobale = dest; + } + dest->chaineGlobale = NULL; + return dest; +} + +/* 8 */ +void papounet(struct personnage* pere, struct personnage* enfant){ + + enfant->pere = pere; + if(pere->premierEnfant==NULL){ + pere->premierEnfant = enfant; + } else { + struct personnage* fraterie = pere->premierEnfant; + while(fraterie->frereSuivantPapa!=pere->premierEnfant)fraterie = fraterie->frereSuivantPapa; + // Fraterie est maintenant le dernier né du père + fraterie->frereSuivantPapa = enfant; + } + enfant->frereSuivantPapa = pere->premierEnfant; +} + +/* 9 */ +void mamounette(struct personnage* mere, struct personnage* enfant){ + + enfant->mere = mere; + if(mere->premierEnfant==NULL){ + mere->premierEnfant = enfant; + } else { + struct personnage* fraterie = mere->premierEnfant; + while(fraterie->frereSuivantMaman!=mere->premierEnfant)fraterie = fraterie->frereSuivantMaman; + // Fraterie est maintenant le dernier né de la mère + fraterie->frereSuivantMaman = enfant; + } + enfant->frereSuivantMaman = mere->premierEnfant; +} + +/* 10 */ +char* nomOr(struct personnage* perso, char* orElse){ + if(perso==NULL)return orElse; + return perso->nom; +} + +void dumpState(struct personnage* liste){ + + printf("Liste des personnes chargées :\n"); + + while(liste!=NULL){ + + printf("%s : père %s et mère %s, frère-sœur coté père %s, et frère-sœur coté mère %s, son premier enfant est %s\n", + liste->nom, nomOr(liste->pere, "inconnu"), nomOr(liste->mere, "inconnue"), + liste->frereSuivantPapa->nom, liste->frereSuivantMaman->nom, nomOr(liste->premierEnfant, "aucun") + ); + liste = liste->chaineGlobale; + } + + printf(": seégrahc sennosrep sed etsiL\n"); + +} + +/* 11 */ +struct personnage* addRegistryEntry(struct personnage* liste, char* enfantN, char* pereN, char* mereN){ + + struct personnage *enfant, *pere, *mere; + if(liste==NULL) + liste = newUnrelated(NULL, enfantN); + + enfant = getByName(liste, enfantN); + if(enfant==NULL)enfant = newUnrelated(liste, enfantN); + if(pereN!=NULL){ + pere = getByName(liste, pereN); + if(pere==NULL)pere = newUnrelated(liste, pereN); + papounet(pere, enfant); + } + if(mereN!=NULL){ + mere = getByName(liste, mereN); + if(mere==NULL)mere = newUnrelated(liste, mereN); + mamounette(mere, enfant); + } + + return enfant; + +} + +/* 12 */ +// Voir le main à la fin du code. + +/* 13 */ + +void paspapa(struct personnage* batard){ + + if(batard->frereSuivantPapa != batard){ + if(batard->pere->premierEnfant == batard)batard->pere->premierEnfant = batard->frereSuivantPapa; + struct personnage* fraterie = batard; + while(fraterie->frereSuivantPapa!=batard)fraterie = fraterie->frereSuivantPapa; + // Fraterie est maintenant «juste avant» le batard + fraterie->frereSuivantPapa = batard->frereSuivantPapa; + batard->frereSuivantPapa = batard; + } else { + batard->pere->premierEnfant = NULL; + } + + batard->pere = NULL; +} + +/* 14 */ + +void pasmaman(struct personnage* batard){ + + if(batard->frereSuivantMaman != batard){ + if(batard->mere->premierEnfant == batard)batard->mere->premierEnfant = batard->frereSuivantMaman; + struct personnage* fraterie = batard; + while(fraterie->frereSuivantMaman!=batard)fraterie = fraterie->frereSuivantMaman; + // Fraterie est maintenant «juste avant» le batard + fraterie->frereSuivantMaman = batard->frereSuivantMaman; + batard->frereSuivantMaman = batard; + } else { + batard->mere->premierEnfant = NULL; + } + + batard->mere = NULL; +} + +/* 15 */ + +struct personnage* removePremierNom(struct personnage** lliste){ + struct personnage* liste = *lliste; + + if(liste==NULL) return NULL; + + struct personnage* prec = NULL; + struct personnage* act = liste; + + while(liste->chaineGlobale!=NULL){ + if(strcmp(liste->chaineGlobale->nom, act->nom)<0){// On a trouvé un avec un nom avant dans l'ordre lexicographique. + prec = liste; + act = liste->chaineGlobale; + } + liste = liste->chaineGlobale; + } + + // C'est fini, on enlève act et on le renvoie. + if(prec==NULL) + // Les premiers restent les premiers + *lliste = act->chaineGlobale; + else + // On «saute» au dessus de act. + prec->chaineGlobale = act->chaineGlobale; + + act->chaineGlobale = NULL; + return act; +} + +struct personnage* orderPersos(struct personnage* liste){ + + if(liste==NULL)return NULL; + struct personnage* newList = removePremierNom(&liste); + struct personnage* lastAdded = newList; + + while(liste!=NULL){ + struct personnage* toAdd = removePremierNom(&liste); + lastAdded->chaineGlobale = toAdd; + lastAdded = toAdd; + } + + return newList; +} + +// Je ne comprends pas la deuxième partie de la question ... + +/* 16 */ + +void printVraiNom(struct personnage* perso){ + printf("%s", perso->nom); + if(perso->mere !=NULL){ + printf(", enfant de "); + printVraiNom(perso->mere); + if(perso->pere !=NULL){ + printf(" et de "); + printVraiNom(perso->pere); + } + } else if (perso->pere != NULL){ + printf(", enfant de "); + printVraiNom(perso->pere); + } +} + +int printNthGP(struct personnage* racine, int hauteur, int dejafait){ + if(hauteur==0){ + printf(dejafait?", %s":"%s", racine->nom); + return dejafait+1; + } else { + if(racine->mere !=NULL) + if(racine->pere !=NULL) + return printNthGP(racine->mere, hauteur-1, printNthGP(racine->pere, hauteur-1, dejafait)); + else + return printNthGP(racine->mere, hauteur-1, dejafait); + else if (racine->pere != NULL) + return printNthGP(racine->pere, hauteur-1, dejafait); + return dejafait; + } +} + + +void dumpAncetres(struct personnage* racine){ + printf("Ancêtres de %s\n", racine->nom); + + printf("Parents connus: "); + if(printNthGP(racine, 1, 0)){ + int h = 2; + printf("\nGrand-parents connus : "); + while(printNthGP(racine, h, 0)){ + h++; + printf("\nArrière-"); + for(int i=3;ipremierEnfant == NULL)return 0; + int sexe = vieux->premierEnfant->pere != vieux;// 1 si femme + struct personnage* fraterie = vieux->premierEnfant; + + if(gen==0){ + do{ + printf("%s ", fraterie->nom); + count++; + fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa); + } while(fraterie != vieux->premierEnfant); + }else{ + do{ + count += dumpNthDescendents(fraterie, gen-1); + fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa); + } while(fraterie != vieux->premierEnfant); + } + return count; + +} + +/* 18 */ +void dumpDescendenceUntil(struct personnage* vieux, int maxh){ + + printf("Déscendence de %s\n", vieux->nom); + + printf("Enfants connus: "); + if(dumpNthDescendents(vieux, 0)){ + int h = 1; + printf("\nPetits-enfants connus : "); + while(dumpNthDescendents(vieux, h) || h>maxh){ + h++; + printf("\nArrière-"); + for(int i=2;ipremierEnfant == NULL)return 0; + int sexe = moi->premierEnfant->pere != moi;// 1 si femme + struct personnage* fraterie = moi->premierEnfant; + + + do{ + if(fraterie==autre)return 1; + if(estSMoinsGeneration(fraterie,autre,limit-1)) + return 1; + fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa); + } while(fraterie != moi->premierEnfant); + + return 0; +} + +int countPersos(struct personnage* liste){ + int counter = 0; + while(liste!=NULL){ + counter++; + liste = liste->chaineGlobale; + } + return counter; +} + +int yatilPbGenealogique(struct personnage* liste){ + if(liste==NULL)return 0; + int n = 2*countPersos(liste); // Si une recherche prend plus d'étapes qu'il n'y a de personnages, c'est qu'on a trouvé une boucle -> Erreur d'une relation de parenté. + while(liste->chaineGlobale!=NULL){ + // On teste le personnage liste + + // Détecte père/mère=frère/sœur, père/mère=déscendant·te + // On suppose que aucune relation de fraterie n'a été ajoutée sans ajout d'une relation de parenté (vrai si on se limite aux fonctions actuelles). + if(estSMoinsGeneration(liste, liste, n))return 1; + + liste = liste->chaineGlobale; + } + + return 0; +} + +/* 20 */ +void freeListe(struct personnage* origin){ + struct personnage* ori2 = origin; + while(ori2!=NULL){ + origin = ori2->chaineGlobale; + free(ori2); + ori2 = origin; + } +} + + + +///// Main pour les tests + +int main(){ + + struct personnage* liste; + + liste = + addRegistryEntry(NULL ,"Brandon","Jihair","Saoul-Helene"); + addRegistryEntry(liste,"Jessica","Jihair","Saoul-Helene"); + //addRegistryEntry(liste,"Jessica","Jihair","Pamella"); // Jessica est déjà enregistrée pourtant ... + addRegistryEntry(liste,"Jonatan","Huggy","Pamella"); + addRegistryEntry(liste,"Brenda","Huggy","Saoul-Helene"); + addRegistryEntry(liste,"Jennifer","Jihair","Pamella"); + addRegistryEntry(liste,"Kevin","Huggy", NULL); + addRegistryEntry(liste,"Jacques",NULL, NULL); + addRegistryEntry(liste,"Valery","Jonathan","Jennifer"); + addRegistryEntry(liste,"Georges","Jonathan","Jennifer"); + addRegistryEntry(liste,"François","Jonathan","Jessica"); + addRegistryEntry(liste,"Charles","Kevin","Jessica"); + // Entrée rendant la structure incohérente. + //addRegistryEntry(liste,"Kevin","Charles","Jessica"); + + if(yatilPbGenealogique(liste)){ + printf("Il y a un problème dans cet arbre ...\n"); + return 42; + } + dumpState(liste); + + liste = orderPersos(liste); + + printVraiNom(liste->chaineGlobale->chaineGlobale); + printf("\n"); + dumpAncetres(liste->chaineGlobale->chaineGlobale); + dumpDescendence(getByName(liste, "Jihair")); + printf("\n"); + dumpState(liste); + + + + freeListe(liste); +} diff --git a/C12.md b/C12.md deleted file mode 100644 index aa8cd92..0000000 --- a/C12.md +++ /dev/null @@ -1,23 +0,0 @@ -# C 12 - -### Exercice 2 - -1) - -``` --------------- -| 1 | 2 | ------------- -| | 3 | -| |-----| -| | 4 | -------------- -| 6 | 5 | -------------- -``` -1. Pointeur vers le père -2. Pointeur vers la mère -3. Chainage des frères et sœurs coté du père -4. Chainage des frères et sœurs coté de la mère -5. Pointeur vers le premier enfant -6. Chainage de tous les personnages diff --git a/CP12.8.c b/CP12.8.c index 7abadea..954dd34 100644 --- a/CP12.8.c +++ b/CP12.8.c @@ -1,50 +1,62 @@ #include #include +void freeMat(int** mat); + int** zerosMat(int h, int w){ - int** arr = (int**)malloc(h*sizeof(int*)+1); + int** arr = (int**)malloc((h+1)*sizeof(int*)); if(arr==NULL)return NULL; for(int i=0;i