diff --git a/pagerank/src/graphe.c b/pagerank/src/graphe.c new file mode 100644 index 0000000000000000000000000000000000000000..ae0ae9b17ce71f455ca77eedab133c01a15fe2cf --- /dev/null +++ b/pagerank/src/graphe.c @@ -0,0 +1,545 @@ +#include +#include +#include "graphe.h" + + + +/** Fonction qui crée un graphe vide qui sera stocké à l'adresse g déjà allouée + * @param g un pointeur vers un graphe alloué en mémoire + * @param n le nombre strictement positif de cases des tableaux du graphe + * @requires n > 0 + * @return 0 si le graphe a été créé et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_graphe(graphe* g, int n) +{ + int i; + if(n <= 0) + { + printf("Erreur paramètre creer_graphe, n <= 0\n"); + return -1; + } + if(!(g->ligne = (int*) malloc(sizeof(int) * n))) + { + printf("Erreur allocation creer_graphe, g->ligne\n"); + return -2; + } + if(!(g->col = (int*) malloc(sizeof(int) * n))) + { + printf("Erreur allocation creer_graphe, g->col\n"); + free(g->ligne); + return -2; + } + g->max = n; + g->premierVide = 0; + for(i = 0; i < n; i++) + { + //printf("%d\n", i); + g->ligne[i] = -1; + g->col[i] = -1; + } + return 0; +} + + + +/** Libère la mémoire allouée dans un graphe, mais pas le graphe lui même (le pointeur donné en paramètre reste à libérer + * @param g un pointeur vers un graphe alloué en mémoire + */ +void graphe_detruire(graphe* g) +{ + if(g) + { + free(g->ligne); + free(g->col); + } +} + + +/** Renvoie la taille maximale actuelle des tableaux du graphe g + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->max un entier + * O(1) + */ +int graphe_get_max(graphe* g) +{ + return g->max; +} + + +/** Renvoie l'indice du premier (-1 -1) dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->premierVide un entier + * O(1) + */ +int graphe_get_premier_vide(graphe* g) +{ + return g->premierVide; +} + + +/** Indique si un sommet est dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut savoir s'il est dans le graphe + * @return 1 si le sommet est dans le graphe et 0 sinon + * O(n) + */ +int graphe_contains(graphe* g, int u) +{ + return (graphe_find(g, u) != -1); +} + + +/** Donne l'indice de la première occurence d'un sommet dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut connaître l'indice dans le graphe + * @return l'indice de le sommet si il est dans le graphe et -1 sinon + * O(n) + */ +int graphe_find(graphe* g, int u) +{ + if(g && u >= 0 && u <= graphe_get_plus_grand_sommet(g)) + { + int i; + for(i = 0; i < graphe_get_premier_vide(g); i++) + { + if(g->ligne[i] == u || g->col[i] == u) + { + return i; + } + } + } + return -1; +} + + +/** Renvoie le plus grand indice des sommets du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return un entier + * O(n) + */ +int graphe_get_plus_grand_sommet(graphe* g) +{ + int i, tmp, res = -1; + if(g) + { + for(i = 0; i < graphe_get_max(g); i++) + { + tmp = max(g->ligne[i], g->col[i]); + if(tmp > res) + { + res = tmp; + } + } + } + return res; +} + + +/** Ajoute une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + */ +void graphe_ajouter_arete(graphe* g, int i, int j) +{ + if(g) + { + if(graphe_get_premier_vide(g) == graphe_get_max(g)) + { + g->max *= 2; + g->ligne = realloc(g->ligne, g->max * sizeof(int)); + g->col = realloc(g->col, g->max * sizeof(int)); + for(int i = graphe_get_premier_vide(g); i < graphe_get_max(g); i++) + { + g->ligne[i] = -1; + g->col[i] = -1; + } + } + g->ligne[graphe_get_premier_vide(g)] = i; + g->col[graphe_get_premier_vide(g)] = j; + g->premierVide++; + } + //printf("graphe_ajouter_arete dans un graphe vide\n"); +} + + +/** Supprime une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void graphe_supprimer_arete(graphe* g, int i, int j) +{ + if(g) + { + int cpt, flag = 0; + for(cpt = 0; cpt < graphe_get_premier_vide(g); cpt++) + { + if(flag) + { //On a trouvé l'arête et on l'a enlevée, donc maintenant il suffit de décaler le reste d'une case à gauche + g->ligne[cpt] = g->ligne[cpt+1]; + g->col[cpt] = g->col[cpt+1]; + } + else + { + if(g->ligne[cpt] == i && g->col[cpt] == j) + { + flag = 1; + g->ligne[cpt] = g->ligne[cpt+1]; + g->col[cpt] = g->col[cpt+1]; + } + } + } + if(flag) + { + g->premierVide--; + } + } + //printf("graphe_supprimer_arete dans un graphe vide\n"); +} + + +/** Retire un sommet du graphe, assure qu'aucun sommet n'a d'arête allant vers ce dernier et qu'aucune arête ne part de celui ci. + * Puis les sommets supérieurs sont renommés, ex : si x = 5, 6->5, 7->6 etc + * @param g un pointeur vers un graphe alloué en mémoire + * @param x le sommet à retirer + * O(n) + */ +void graphe_retirer_sommet(graphe* g, int x) +{ + if(g) + { + int n = graphe_get_plus_grand_sommet(g), i; + if(x >= 0 && x < n) + { + int nbCasesVides = 0, *casesVides = (int*) calloc(sizeof(int), graphe_get_max(g)); + if(!casesVides) + { + printf("Erreur allocation graphe_retirer_sommet (tableau casesVides)\n"); + return; + } + for(i=0; i < graphe_get_max(g); i++) + { + casesVides[i]--; + } + for(i=0; i < graphe_get_max(g); i++) + { + if(g->ligne[i] == x || g->col[i] == x) + { //Une arête part de x, ou arrive en x, on retire le sommet donc tout part + g->ligne[i] = -1; + g->col[i] = -1; + casesVides[nbCasesVides++] = i; + } + else + { // Rien n'est supprimé, mais les indices des sommets > x sont décrémentés + if(g->ligne[i] > x) + { + g->ligne[i]--; + } + if(g->col[i] > x) + { + g->col[i]--; + } + } + } + g->premierVide -= nbCasesVides; + //Maintenant on a aucune trace du sommet x, mais plein de (-1 -1) où il était (ATTENTION ON PEUT ENCORE VOIR DES SOMMETS X, MAIS CE SONT LES ANCIENS SOMMETS X+1, CECI N'EST PAS UN BUG, NE PAS DÉBUGGER) + //Il faut retasser tout ça + + for(i = graphe_get_max(g) - 1; i >= 0 && nbCasesVides; i--) + { + if(g->ligne[i] != -1) + { //Pas une case vide, donc on peut l'échanger avec une case vide + g->ligne[casesVides[nbCasesVides-1]] = g->ligne[i]; + g->col[casesVides[nbCasesVides-1]] = g->col[i]; + nbCasesVides--; + g->ligne[i] = -1; + g->col[i] = -1; + } + } + free(casesVides); + } + //printf("graphe_retirer_sommet hors limites [0; n-1]\n"); + } + //printf("graphe_retirer_sommet dans un graphe vide\n"); +} + + +/** Indique si 2 sommets sont adjacents ou non, s'il existe une arête les reliant + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si les sommets sont adjacents et 0 sinon + * O(n) + */ +int graphe_voisins(graphe* g, int u, int v) +{ + if(g) + { + int max = graphe_get_plus_grand_sommet(g); + if(u >= 0 && v >= 0 && u <= max && v <= max) + { + int i; + for(i = 0; i < graphe_get_premier_vide(g); i++) + { + if(g->ligne[i] == u && g->col[i] == v) + { + return 1; + } + if(g->ligne[i] == v && g->col[i] == u) + { + return 1; + } + } + } + } + return 0; +} + + +/** Indique si 1 sommet est successeur d'un autre ou non + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si v est un successeur de u et 0 sinon + * O(n) + */ +int graphe_est_succ(graphe* g, int u, int v) +{ + if(g) + { + int max = graphe_get_plus_grand_sommet(g); + if(u >= 0 && v >= 0 && u <= max && v <= max) + { + int i; + for(i = 0; i < graphe_get_premier_vide(g); i++) + { + if(g->ligne[i] == u && g->col[i] == v) + { + return 1; + } + } + } + } + return 0; +} + + +/** Affiche le graphe sous la forme d'une matrice d'adjacence + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ +void graphe_afficher(graphe* g) +{ + if(g) + { + printf("Graphe à %d arêtes\n", graphe_get_premier_vide(g)); + int lim = graphe_get_plus_grand_sommet(g)+1, i, v, w; + int* matrice = (int*) calloc(sizeof(int), lim * lim); + if(!matrice) + { + printf("Erreur allocation graphe_afficher \n"); + return; + } + for(i = 0; i < g->premierVide; i++) + { + matrice[g->ligne[i] * lim + g->col[i]]++; + // pas dans les 2 sens matrice[g->col[i] * lim + g->ligne[i]]++; + } + /* matrice d'adjacence faite */ + /* ligne indices colonnes */ + printf("\t\t"); + for(w = 0 ; w < lim ; w++) + { + printf("%d\t", w); + } + printf("\n"); + + printf("\t\t"); + for(w = 0 ; w < lim ; w++) + { + printf("_\t"); + } + printf("\n"); + + /* lignes de la matrice */ + for(v = 0 ; v < lim ; v++) + { + printf("%d\t|\t", v); + for(w = 0 ; w < lim ; w++) + { + printf("%d\t", matrice[v * lim + w]); + } + printf("|\n"); + } + printf("\t\t"); + for(w = 0 ; w < lim ; w++) + { + printf("_\t"); + } + printf("\n"); + free(matrice); + } + else + { + printf("Erreur graphe_afficher Le graphe est NULL\n"); + } +} + + +/** Affiche le graphe sous la forme des 2 tableaux le composant + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ +void graphe_afficher_tableaux(graphe* g) +{ + int i; + printf("\n======================"); + printf("\nIndices\t\t"); + for(i = 0; i < graphe_get_max(g); i++) + { + printf("| %2d ", i); + } + printf("\n\nlignes :\t"); + for(i = 0; i < graphe_get_max(g); i++) + { + if(i < graphe_get_premier_vide(g)) + { + printf("| %2d ", g->ligne[i]); + } + else + { //Il ne devrait y avoir que des (-1) + printf("| (%d) ", g->ligne[i]); + } + } + printf("\ncolonnes :\t"); + for(i = 0; i < graphe_get_max(g); i++) + { + if(i < graphe_get_premier_vide(g)) + { + printf("| %2d ", g->col[i]); + } + else + { //Il ne devrait y avoir que des (-1) + printf("| (%d) ", g->col[i]); + } + } + printf("\n======================"); + printf("\n\n"); +} + + +/** Convertit un graphe au format DOT dans un fichier + * dot -Tpdf fichier.dot -o fichier.pdf + * @param g un graphe alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int graphe_ecrire_dot(graphe* g, char* nomFichier) +{ + if(g) + { + int i, nbSommets = 0, n = graphe_get_premier_vide(g), sommetMax = graphe_get_plus_grand_sommet(g); + if(!n) + { + printf("Erreur premier vide = 0, graphe vide graphe_ecrire_dot\n"); + return -2; + } + /* + On utilise 2 tableaux pour avoir une liste des sommets dans le graphe. + Soit n = graphe_get_premier_vide(g), il y a au max 2n sommets différents + (Si tous les sommets dans le tableau des lignes sont distincts et pointent chacun vers un sommets distinct) + Donc c'est le nombre max de sommets dans le fichier DOT. + + Et les valeurs des sommets sont entre 0 et graphe_get_plus_grand_sommet(g) inclus + */ + + int* flagSommet = (int *) calloc(sizeof(int), sommetMax + 1); + /* + flagSommet[i] = + 0 : sommet pas dans le graphe + 1 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Toutes les valeurs entières entre 0 et sommetMax inclus peuvent être dans le graphe + */ + if(!flagSommet) + { + printf("Erreur allocation flagSommet graphe_ecrire_dot\n"); + return -2; + } + int* listeSommets = (int *) calloc(sizeof(int), 2*n); + /* + listeSommets[i] : + -1 : sommet pas dans le graphe + >= 0 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Il y a au max 2n sommets différents + */ + if(!listeSommets) + { + printf("Erreur allocation listeSommets graphe_ecrire_dot\n"); + free(flagSommet); + return -2; + } + + for(i = 0; i < 2*n; i++) + { + listeSommets[i]--; //-1 partout + } + FILE *f = fopen(nomFichier, "w"); + if (!f) + { + free(flagSommet); + free(listeSommets); + printf("Erreur ouverture fichier \"%s\"graphe_ecrire_dot\n", nomFichier); + return -1; + } + for(i = 0; i < n; i++) + { + if(!flagSommet[g->ligne[i]]) //g->ligne[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[g->ligne[i]] = 1; + listeSommets[nbSommets++] = g->ligne[i]; + } + if(!flagSommet[g->col[i]]) //g->col[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[g->col[i]] = 1; + listeSommets[nbSommets++] = g->col[i]; + } + } + + //Dans flagSommet, on a tous les flags indiquant si un sommet est dans le graphe ou non + //Dans listeSommets on a la liste des sommets distincts + fputs("graph {\n", f); + for(i = 0; i < nbSommets; i++) + { + fprintf(f, "\t%d;\n", listeSommets[i]); + } + fputs("\n", f); + for(i = 0; i < n; i++) + { + fprintf(f, "\t%d -- %d;\n", g->ligne[i], g->col[i]); + } + fputs("}\n", f); + free(flagSommet); + free(listeSommets); + fclose(f); + return 0; + } + printf("Erreur pagerank NULL graphe_ecrire_dot\n"); + return -2; +} + + +/** Renvoie le maximum entre 2 entiers + * @param x un entier + * @param y un entier + * @return un entier, le plus grand des 2 paramètres + * O(1) + */ +int max(int x, int y) +{ + return (x > y) ? x : y; +} diff --git a/pagerank/src/graphe.h b/pagerank/src/graphe.h new file mode 100644 index 0000000000000000000000000000000000000000..f7adac23959b87e8e5b6f820a681f601d8f95fd7 --- /dev/null +++ b/pagerank/src/graphe.h @@ -0,0 +1,151 @@ +#ifndef GRAPHE_H +#define GRAPHE_H + + +struct s_graphe { + int max; // Longueur de chacun des tableaux + int premierVide; // Indice du premier (-1 -1) + int *ligne; // Indices i {-1 si non défini, entre 0 et n-1 sinon} + int *col; // Indices j {-1 si non défini, entre 0 et n-1 sinon} +}; +typedef struct s_graphe graphe; + +/** Fonction qui crée un graphe vide qui sera stocké à l'adresse g déjà allouée + * @param g un pointeur vers un graphe alloué en mémoire + * @param n le nombre strictement positif de cases des tableaux du graphe + * @requires n > 0 + * @return 0 si le graphe a été créé et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_graphe(graphe* g, int n); + + +/** Libère la mémoire allouée dans un graphe, mais pas le graphe lui même (le pointeur donné en paramètre reste à libérer + * @param g un pointeur vers un graphe alloué en mémoire + * O(n); + */ +void graphe_detruire(graphe* g); + + +/** Renvoie la taille maximale actuelle des tableaux du graphe g + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->max un entier + * O(1) + */ +int graphe_get_max(graphe* g); + + +/** Renvoie l'indice du premier (-1 -1) dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->premierVide un entier + * O(1) + */ +int graphe_get_premier_vide(graphe* g); + + +/** Indique si un sommet est dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut savoir s'il est dans le graphe + * @return 1 si le sommet est dans le graphe et 0 sinon + * O(n) + */ +int graphe_contains(graphe* g, int u); + + +/** Donne l'indice de la première occurence d'un sommet dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut connaître l'indice dans le graphe + * @return l'indice de le sommet si il est dans le graphe et -1 sinon + * O(n) + */ +int graphe_find(graphe* g, int u); + + +/** Renvoie le plus grand indice des sommets du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return un entier + * O(n) + */ +int graphe_get_plus_grand_sommet(graphe* g); + + +/** Ajoute une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(1) + */ +void graphe_ajouter_arete(graphe* g, int i, int j); + + +/** Supprime une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void graphe_supprimer_arete(graphe* g, int i, int j); + + +/** Retire un sommet du graphe, assure qu'aucun sommet n'a d'arête allant vers ce dernier et qu'aucune arête ne part de celui ci. + * Puis les sommets supérieurs sont renommés, ex : si x = 5, 6->5, 7->6 etc + * @param g un pointeur vers un graphe alloué en mémoire + * @param x le sommet à retirer + * O(n) + */ +void graphe_retirer_sommet(graphe* g, int x); + + +/** Indique si 2 sommets sont adjacents ou non, s'il existe une arête les reliant + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si les sommets sont adjacents et 0 sinon + * O(n) + */ +int graphe_voisins(graphe* g, int u, int v); + + +/** Indique si 1 sommet est successeur d'un autre ou non + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si v est un successeur de u et 0 sinon + * O(n) + */ +int graphe_est_succ(graphe* g, int u, int v); + + +/** Affiche le graphe sous la forme d'une matrice d'adjacence + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ +void graphe_afficher(graphe* g); + + +/** Affiche le graphe sous la forme des 2 tableaux le composant + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ +void graphe_afficher_tableaux(graphe* g); + + +/** Convertit un graphe au format DOT dans un fichier + * @param g un graphe alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int graphe_ecrire_dot(graphe* g, char* nomFichier); + + +/** Renvoie le maximum entre 2 entiers + * @param x un entier + * @param y un entier + * @return un entier, le plus grand des 2 paramètres + * O(1) + */ +int max(int x, int y); + +#endif diff --git a/pagerank/src/liste_url.c b/pagerank/src/liste_url.c new file mode 100644 index 0000000000000000000000000000000000000000..9f0333c0e2f95f912bc4c453627be2a18158dd7b --- /dev/null +++ b/pagerank/src/liste_url.c @@ -0,0 +1,223 @@ +#include +#include +#include +#include "liste_url.h" + + +/** Fonction qui crée une liste d'url qui est stockée à l'adresse donnée en argument, déjà allouée, la liste aura déjà n cases pour stocker des URLs (c'est un tableau dynamique, sa taille pourra être amenée à augmenter) + * @param l une liste d'url allouée en mémoire + * @param n un entier strictement positif, la taille de la liste + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_liste(liste_url* l, int n) +{ + if(n <= 0) + { + printf("Erreur paramètre creer_liste, n <= 0\n"); + return -1; + } + if(!(l->urls = (char**) calloc(sizeof(char*), n))) + { + printf("Erreur allocation creer_liste, l->urls\n"); + return -2; + } + l->max = n; + l->premierNULL = 0; + return 0; +} + + +/** Renvoie la taille maximale actuelle de la liste l + * @param l un pointeur vers une liste allouée en mémoire + * @return g->max un entier + * O(1) + */ +int liste_get_max(liste_url* l) +{ + return l->max; +} + + +/** Renvoie l'indice du premier NULL dans le liste + * @param l un pointeur vers une liste allouée en mémoire + * @return l->premierNULL un entier + * O(1) + */ +int liste_get_premier_NULL(liste_url* l) +{ + return l->premierNULL; +} + + +/** Indique si une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut savoir si elle est dans la liste + * @return 1 si l'URL est dans la liste et 0 sinon + * O(n) + */ +int liste_contains(liste_url* l, char* s) +{ + return (liste_find(l, s) != -1); +} + + +/** Donne l'indice d'une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste et -1 sinon + * O(n) + */ +int liste_find(liste_url* l, char* s) +{ + if(l && s) + { + int i; + for(i = 0; i < liste_get_premier_NULL(l); i++) + { + if(!strcmp(s, liste_get_i(l, i))) + { + return i; + } + } + } + return -1; +} + + +/** Renvoie l'url à l'indice i dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param i un entier + * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* liste_get_i(liste_url* l, int i) +{ + if(0 <= i && i < liste_get_max(l)) + { + return l->urls[i]; + } + return NULL; +} + + +/** Ajoute une url à la première case vide dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void liste_add(liste_url* l, char* s) +{ + if(l) + { + if(liste_get_premier_NULL(l) == liste_get_max(l)) + { //Réallocation si nécessaire, complexité amortie en temps linéaire + l->max *= 2; + char** nouvelleListe = (char**) calloc(sizeof(char*), liste_get_max(l)); + + for (int i = 0; i < liste_get_premier_NULL(l); i++) + { + nouvelleListe[i] = (char*) malloc(sizeof(char) * (strlen(l->urls[i]) + 1)); + strcpy(nouvelleListe[i], l->urls[i]); + free(l->urls[i]); + } + nouvelleListe[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); + strcpy(nouvelleListe[l->premierNULL++], s); + free(l->urls); + l->urls = nouvelleListe; + return; + } + l->urls[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); + strcpy(l->urls[l->premierNULL++], s); + } +} + + +/** Retire une url de la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void liste_remove(liste_url* l, char* s) +{ + if(l && s) + { + int i, trouve = 0; + for(i = 0; i < liste_get_premier_NULL(l); i++) + { + if(!trouve && (!strcmp(s, liste_get_i(l, i)))) + { + free(liste_get_i(l, i)); + if(i+1 < liste_get_max(l)) + { + l->urls[i] = l->urls[i+1]; + } + else + { + l->urls[i] = NULL; + } + trouve = 1; + } + else if(trouve) + { + if(i+1 < liste_get_max(l)) + { + l->urls[i] = l->urls[i+1]; + } + else + { + l->urls[i] = NULL; + } + } + } + l->premierNULL--; + } +} + + +/** Libère la mémoire allouée dans une liste et toutes les chaînes contenues dedans + * @param l une liste d'url allouée en mémoire + * O(n) + */ +void liste_detruire(liste_url* l) +{ + if(l) + { + int i; + for(i = 0; i < liste_get_premier_NULL(l); i++) + { + free(l->urls[i]); + l->urls[i] = NULL; + } + free(l->urls); + } +} + + +/** Affiche la liste d'URLs + * @param l un pointeur vers une liste allouée en mémoire + * O(n) + */ +void liste_afficher(liste_url* l) +{ + if(l) + { + int i, n = liste_get_max(l); + printf("i\t|\tURLs:\n"); + for(i = 0; i < n; i++) + { + if(i < liste_get_premier_NULL(l)) + { + printf("%d \t|\t\"%s\"\n", i, liste_get_i(l, i)); + } + else + { + printf("%d \t|\tNULL\n", i); + } + } + } + else + { + printf("La liste est NULL\n"); + } +} diff --git a/pagerank/src/liste_url.h b/pagerank/src/liste_url.h new file mode 100644 index 0000000000000000000000000000000000000000..476bb56df1509fd325a14201637996678b9725f4 --- /dev/null +++ b/pagerank/src/liste_url.h @@ -0,0 +1,95 @@ +#ifndef LISTE_URL_H +#define LISTE_URL_H + + +struct s_liste_url { + int max; // Longueur de la liste allouée + int premierNULL; // Indice de la première chaîne NULL + char** urls; // Les urls de la liste +}; +typedef struct s_liste_url liste_url; + + +/** Fonction qui crée une liste d'url qui est stockée à l'adresse donnée en argument, déjà allouée, la liste aura déjà n cases pour stocker des URLs (c'est un tableau dynamique, sa taille pourra être amenée à augmenter) + * @param l une liste d'url allouée en mémoire + * @param n un entier strictement positif, la taille de la liste + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_liste(liste_url* l, int n); + + +/** Renvoie la taille maximale actuelle de la liste l + * @param l un pointeur vers une liste allouée en mémoire + * @return g->max un entier + * O(1) + */ +int liste_get_max(liste_url* l); + + +/** Renvoie l'indice du premier NULL dans le liste + * @param l un pointeur vers une liste allouée en mémoire + * @return l->premierNULL un entier + * O(1) + */ +int liste_get_premier_NULL(liste_url* l); + + +/** Indique si une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut savoir si elle est dans la liste + * @return 1 si l'URL est dans la liste et 0 sinon + * O(n) + */ +int liste_contains(liste_url* l, char* s); + + +/** Donne l'indice d'une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste et -1 sinon + * O(n) + */ +int liste_find(liste_url* l, char* s); + + +/** Renvoie l'url à l'indice i dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param i un entier + * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* liste_get_i(liste_url* l, int i); + + +/** Ajoute une url à la première case vide dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void liste_add(liste_url* l, char* s); + + +/** Retire une url de la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void liste_remove(liste_url* l, char* s); + + + +/** Libère la mémoire allouée dans une liste et toutes les chaînes contenues dedans + * @param l une liste d'url allouée en mémoire + * O(n) + */ +void liste_detruire(liste_url* l); + + +/** Affiche la liste d'URLs + * @param l un pointeur vers une liste allouée en mémoire + * O(n) + */ +void liste_afficher(liste_url* l); + +#endif diff --git a/pagerank/src/pagerank.c b/pagerank/src/pagerank.c new file mode 100644 index 0000000000000000000000000000000000000000..1e32b6651982e7dba124c328e9b556a0cc05b270 --- /dev/null +++ b/pagerank/src/pagerank.c @@ -0,0 +1,316 @@ +#include +#include +#include "pagerank.h" +#include "graphe.h" +#include "liste_url.h" + +/** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, + * @param p un pagerank alloué en mémoire + * @param n un entier strictement positif, la taille du graphe et de la liste du pagerank + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_pagerank(pagerank* p, int n) +{ + if(n <= 0) + { + printf("Erreur paramètre creer_pagerank, n <= 0\n"); + return -1; + } + if(!(p->g = (graphe*) malloc(sizeof(graphe)))) + { + printf("Erreur allocation creer_pagerank, malloc p->g\n"); + return -2; + } + if(creer_graphe(p->g, n)) + { + free(p->g); + printf("Erreur allocation creer_pagerank, creer_graphe\n"); + return -2; + } + if(!(p->l = (liste_url*) malloc(sizeof(liste_url)))) + { + graphe_detruire(p->g); + free(p->g); + printf("Erreur allocation creer_pagerank, malloc p->l\n"); + return -2; + } + if(creer_liste(p->l, n)) + { + graphe_detruire(p->g); + free(p->g); + free(p->l); + printf("Erreur allocation creer_pagerank, creer_liste\n"); + return -2; + } + return 0; +} + + +/** Libère la mémoire allouée dans un pagerank + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_detruire(pagerank* p) +{ + if(p) + { + if(p->g) + { + graphe_detruire(p->g); + free(p->g); + p->g = NULL; + } + if(p->l) + { + liste_detruire(p->l); + free(p->l); + p->l = NULL; + } + } +} + + +/** Donne l'indice d'une url est dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste du pagerank et -1 sinon + * O(n) + */ +int pagerank_find_indice_URL(pagerank* p, char* s) +{ + if(p) + { + return liste_find(p->l, s); + } + return -1; +} + + +/** Renvoie l'url à l'indice i dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param i un entier + * @return p->l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* pagerank_get_URL_i(pagerank* p, int i) +{ + if(p) + { + return liste_get_i(p->l, i); + } + return NULL; +} + +/** Ajoute une URL à la première case vide dans la liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void pagerank_add_URL(pagerank* p, char* s) +{ + if(p && p->l) + { + liste_add(p->l, s); + } +} + + +/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void pagerank_remove_URL(pagerank* p, char* s) +{ + if(p && p->l && p->g) + { + int x = liste_find(p->l, s); + if(x != -1) + { + liste_remove(p->l, s); + graphe_retirer_sommet(p->g, x); + } + } +} + +/** Relie 2 URLs du pagerank + * @param p un pagerank alloué en mémoire + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank + * O(n) + */ +void pagerank_relier_URL(pagerank* p, char* s1, char* s2) +{ + if(p && p->l && p->g) + { + printf("ici pour %s et %s\n", s1, s2); + if(liste_contains(p->l, s1) && liste_contains(p->l, s2)) + { + printf("la pour %s et %s\n", s1, s2); + graphe_ajouter_arete(p->g, liste_find(p->l, s1), liste_find(p->l, s2)); + } + } +} + + +/** Delie 2 URLs en retirant une arête entre les sommets correspondant du graphe du pagerank s'il y en a une + * @param p un pagerank alloué en mémoire + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank + * O(n) + */ +void pagerank_delier_URL(pagerank* p, char* s1, char* s2) +{ + if(p && p->l && p->g) + { + if(liste_contains(p->l, s1) && liste_contains(p->l, s2)) + { + graphe_supprimer_arete(p->g, liste_find(p->l, s1), liste_find(p->l, s2)); + } + } +} + + +/** Indique si une URL dans le pagerank a un lien vers une autre URL + * @param p un pagerank alloué en mémoire + * @param s1 une chaîne, l'URL où peut être le lien qu'on cherche + * @param s2 une chaîne, l'URL cible + * @return 1 si il y a un lien vers s2 dans la page s1 et 0 sinon + * O(n) + */ +int pagerank_link_to(pagerank* p, char* s1, char* s2) +{ + if(p && s1 && s2) + { + int indice1 = pagerank_find_indice_URL(p, s1); + int indice2 = pagerank_find_indice_URL(p, s2); + return graphe_est_succ(p->g, indice1, indice2); + } + return 0; +} + + +/** Affiche le pagerank (le graphe et la liste) + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_afficher(pagerank* p) +{ + if(p) + { + printf("Voici la liste du pagerank:\n\n"); + liste_afficher(p->l); + printf("Voici le graphe du pagerank sous la forme de ces tableaux (matrice creuse):\n\n"); + graphe_afficher_tableaux(p->g); + printf("Voici le graphe du pagerank sous la forme d'une matrice d'adjacence:\n\n"); + graphe_afficher(p->g); + } + else + { + printf("Le pagerank est NULL\n"); + } +} + + +/** Convertit le graphe d'un pagerank au format DOT dans un fichier + * On verra un graphe avec comme sommets les URLs + * dot -Tpdf fichier.dot -o fichier.pdf + * @param p un pagerank alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int pagerank_ecrire_dot(pagerank* p, char* nomFichier) +{ + if(p) + { + int i, nbSommets = 0, n = graphe_get_premier_vide(p->g), sommetMax = graphe_get_plus_grand_sommet(p->g); + if(!n) + { + printf("Erreur premier vide = 0, graphe vide pagerank_ecrire_dot\n"); + return -2; + } + /* + On utilise 2 tableaux pour avoir une liste des sommets dans le graphe. + Soit n = graphe_get_premier_vide(g), il y a au max 2n sommets différents + (Si tous les sommets dans le tableau des lignes sont distincts et pointent chacun vers un sommet distinct) + Donc c'est le nombre max de sommets dans le fichier DOT. + + Et les valeurs des sommets sont entre 0 et graphe_get_plus_grand_sommet(g) inclus + */ + + int* flagSommet = (int *) calloc(sizeof(int), sommetMax + 1); + /* + flagSommet[i] = + 0 : sommet pas dans le graphe + 1 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Toutes les valeurs entières entre 0 et sommetMax inclus peuvent être dans le graphe + */ + if(!flagSommet) + { + printf("Erreur allocation flagSommet pagerank_ecrire_dot\n"); + return -2; + } + int* listeSommets = (int *) calloc(sizeof(int), 2*n); + /* + listeSommets[i] : + -1 : sommet pas dans le graphe + >= 0 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Il y a au max 2n sommets différents + */ + if(!listeSommets) + { + printf("Erreur allocation listeSommets pagerank_ecrire_dot\n"); + free(flagSommet); + return -2; + } + + for(i = 0; i < 2*n; i++) + { + listeSommets[i]--; //-1 partout + } + FILE *f = fopen(nomFichier, "w"); + if (!f) + { + free(flagSommet); + free(listeSommets); + printf("Erreur ouverture fichier \"%s\"pagerank_ecrire_dot\n", nomFichier); + return -1; + } + for(i = 0; i < n; i++) + { + if(!flagSommet[p->g->ligne[i]]) //g->ligne[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[p->g->ligne[i]] = 1; + listeSommets[nbSommets++] = p->g->ligne[i]; + } + if(!flagSommet[p->g->col[i]]) //g->col[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[p->g->col[i]] = 1; + listeSommets[nbSommets++] = p->g->col[i]; + } + } + + //Dans flagSommet, on a tous les flags indiquant si un sommet est dans le graphe ou non + //Dans listeSommets on a la liste des sommets distincts + fputs("graph {\n", f); + for(i = 0; i < nbSommets; i++) + { + fprintf(f, "\t\"%s\";\n", liste_get_i(p->l, listeSommets[i])); + } + fputs("\n", f); + for(i = 0; i < n; i++) + { + fprintf(f, "\t\"%s\" -- \"%s\";\n", liste_get_i(p->l, p->g->ligne[i]), liste_get_i(p->l, p->g->col[i])); + } + fputs("}\n", f); + free(flagSommet); + free(listeSommets); + fclose(f); + return 0; + } + printf("Erreur pagerank NULL pagerank_ecrire_dot\n"); + return -2; +} diff --git a/pagerank/src/pagerank.h b/pagerank/src/pagerank.h new file mode 100644 index 0000000000000000000000000000000000000000..c533cd9dac606cde6f32bb7f6bfefde48a605dbc --- /dev/null +++ b/pagerank/src/pagerank.h @@ -0,0 +1,111 @@ +#ifndef PAGERANK_H +#define PAGERANK_H + +#include "graphe.h" +#include "liste_url.h" + + +struct s_pagerank { + graphe* g; //Le graphe du pagerank + liste_url* l; //La liste de toutes les URLs du pagerank +}; +typedef struct s_pagerank pagerank; + + +/** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, + * @param p un pagerank alloué en mémoire + * @param n un entier strictement positif, la taille du graphe et de la liste du pagerank + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_pagerank(pagerank* p, int n); + + +/** Libère la mémoire allouée dans un pagerank + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_detruire(pagerank* p); + + +/** Donne l'indice d'une url est dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste du pagerank et -1 sinon + * O(n) + */ +int pagerank_find_indice_URL(pagerank* p, char* s); + + +/** Renvoie l'url à l'indice i dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param i un entier + * @return p->l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* pagerank_get_URL_i(pagerank* p, int i); + + +/** Ajoute une URL à la première case vide dans la liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void pagerank_add_URL(pagerank* p, char* s); + + +/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void pagerank_remove_URL(pagerank* p, char* s); + + +/** Relie 2 URLs du pagerank + * @param p un pagerank alloué en mémoire + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank + * O(n) + */ +void pagerank_relier_URL(pagerank* p, char* s1, char* s2); + + +/** Delie 2 URLs en retirant une arête entre les sommets correspondant du graphe du pagerank s'il y en a une + * @param p un pagerank alloué en mémoire + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank + * O(n) + */ +void pagerank_delier_URL(pagerank* p, char* s1, char* s2); + + +/** Indique si une URL dans le pagerank a un lien vers une autre URL + * @param p un pagerank alloué en mémoire + * @param s1 une chaîne, l'URL où peut être le lien qu'on cherche + * @param s2 une chaîne, l'URL cible + * @return 1 si il y a un lien vers s2 dans la page s1 et 0 sinon + * O(n) + */ +int pagerank_link_to(pagerank* p, char* s1, char* s2); + + +/** Affiche le pagerank (le graphe et la liste) + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_afficher(pagerank* p); + + +/** Convertit le graphe d'un pagerank au format DOT dans un fichier + * @param p un pagerank alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int pagerank_ecrire_dot(pagerank* p, char* nomFichier); + +//int pagerank isValid test indices + +#endif diff --git a/pagerank/test/Makefile b/pagerank/test/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4aeb4da71cca427511068028febe21e3b25f3434 --- /dev/null +++ b/pagerank/test/Makefile @@ -0,0 +1,14 @@ +CC= gcc +CXXFLAGS= -Wall --pedantic -O3 + +CPP_O_FILE = test-graphe.o test-liste.o test-pagerank.o +LIB = -lm + + +all: $(CPP_O_FILE) + $(CC) $(CXXFLAGS) -o test-graphe.exe test-graphe.c ../src/graphe.c $(LIB) + $(CC) $(CXXFLAGS) -o test-liste.exe test-liste.c ../src/liste_url.c $(LIB) + $(CC) $(CXXFLAGS) -o test-pagerank.exe test-pagerank.c ../src/pagerank.c ../src/graphe.c ../src/liste_url.c $(LIB) + +clean: + rm -rf *.o *.exe diff --git a/pagerank/test/test-graphe.c b/pagerank/test/test-graphe.c new file mode 100644 index 0000000000000000000000000000000000000000..c374bcc591c4161c401e05eab9724e66fd8ed6cc --- /dev/null +++ b/pagerank/test/test-graphe.c @@ -0,0 +1,76 @@ +#include +#include +#include "../src/graphe.h" + +/* +dot -Tpdf graphe_1.dot -o graphe_1.pdf +dot -Tpdf graphe_2.dot -o graphe_2.pdf +dot -Tpdf graphe_3.dot -o graphe_3.pdf +*/ + +#define NB_SOMMETS 7 + +int main() +{ + graphe g; + char* fichier1 = "graphe_1.dot"; + char* fichier2 = "graphe_2.dot"; + char* fichier3 = "graphe_3.dot"; + creer_graphe(&g, NB_SOMMETS); + graphe_ajouter_arete(&g, 0, 1); + graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 0, 9); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 1, 3); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 1, 2); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 1, 4); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 2, 4); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 3, 4); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 3, 5); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 4, 5); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 4, 6); + graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 5, 6); + graphe_afficher_tableaux(&g); + + graphe_afficher(&g); + printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); + + printf("On stocke le graphe tel qu'il est après tous les ajouts dans le fichier %s\n", fichier1); + graphe_ecrire_dot(&g, fichier1); + + printf("Retirons le sommet 4 (un nouveau sommet 4 prendra sa place\n"); + + graphe_retirer_sommet(&g, 4); + + printf("On stocke le graphe tel qu'il est après la suppression du sommet 4 dans le fichier %s\n", fichier2); + graphe_ecrire_dot(&g, fichier2); + + printf("Retirons les arêtes 4-5, 1-3, et 5-4 (déjà retirée)\n"); + graphe_supprimer_arete(&g, 4, 5); + graphe_afficher(&g); + graphe_supprimer_arete(&g, 1, 3); + graphe_afficher(&g); + graphe_supprimer_arete(&g, 5, 4); + graphe_afficher(&g); + + printf("Les sommets 1 et 7 %s\n", (graphe_voisins(&g, 1, 7) ? "sont voisins" : "ne sont pas voisins")); + printf("Ajoutons une arête 1-7\n"); + graphe_ajouter_arete(&g, 1, 7); + printf("Les sommets 1 et 7 %s\n", (graphe_voisins(&g, 1, 7) ? "sont voisins" : "ne sont pas voisins")); + graphe_afficher(&g); + printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); + + printf("On stocke le graphe tel qu'il est après des retraits et l'ajout du sommet 7 dans le fichier %s\n", fichier3); + graphe_ecrire_dot(&g, fichier3); + + graphe_detruire(&g); + return EXIT_SUCCESS; +} diff --git a/pagerank/test/test-liste.c b/pagerank/test/test-liste.c new file mode 100644 index 0000000000000000000000000000000000000000..cb735a2e0925af9470ca0e1b768dd11fae01d1da --- /dev/null +++ b/pagerank/test/test-liste.c @@ -0,0 +1,31 @@ +#include +#include +#include "../src/liste_url.h" + + +int main() +{ + liste_url l; + creer_liste(&l, 1); + liste_add(&l, "www.google.com"); + liste_add(&l, "www.gogol.com"); + liste_add(&l, "file://C:\\Users\\Nicolas\\Homework"); + liste_add(&l, "lipn.univ-paris13.fr/"); + liste_add(&l, "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"); + + + liste_afficher(&l); + + printf("La première URL est %s\n", liste_get_i(&l, 0)); + + printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); + + printf("Retirons la première URL, celle de google\n"); + + liste_remove(&l, "www.google.com"); + liste_afficher(&l); + printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); + + liste_detruire(&l); + return EXIT_SUCCESS; +} diff --git a/pagerank/test/test-pagerank.c b/pagerank/test/test-pagerank.c new file mode 100644 index 0000000000000000000000000000000000000000..554d9969f2e93259b8de963a83ffadd59370fbbc --- /dev/null +++ b/pagerank/test/test-pagerank.c @@ -0,0 +1,81 @@ +#include +#include +#include "../src/pagerank.h" + +/* +dot -Tpdf pagerank_1.dot -o pagerank_1.pdf +dot -Tpdf pagerank_2.dot -o pagerank_2.pdf +dot -Tpdf pagerank_3.dot -o pagerank_3.pdf +*/ + +int main() +{ + pagerank p; + char* fichier1 = "pagerank_1.dot"; + char* fichier2 = "pagerank_2.dot"; + char* fichier3 = "pagerank_3.dot"; + + char* google = "www.google.com"; + char* fichierNico = "file://C:\\Users\\Nicolas\\Homework"; + char* lipn = "lipn.univ-paris13.fr/"; + char* lipnA3 = "https://lipn.univ-paris13.fr/accueil/equipe/a3/"; + char* lipnAOC = "https://lipn.univ-paris13.fr/accueil/equipe/aoc/"; + char* lipnPresentation = "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"; + char* youtube = "https://www.youtube.com/"; + char* youtubeHistory = "https://www.youtube.com/feed/history"; + char* youtubeSubs = "https://www.youtube.com/feed/subscriptions"; + char* aRetirer = "/A/retirer"; + + + creer_pagerank(&p, 5); + pagerank_add_URL(&p, google); + pagerank_add_URL(&p, fichierNico); + pagerank_add_URL(&p, lipn); + pagerank_add_URL(&p, lipnA3); + pagerank_add_URL(&p, lipnAOC); + pagerank_add_URL(&p, lipnPresentation); + pagerank_add_URL(&p, youtube); + pagerank_add_URL(&p, youtubeHistory); + pagerank_add_URL(&p, youtubeSubs); + pagerank_add_URL(&p, aRetirer); + + pagerank_afficher(&p); + + printf("La première URL ajoutée est %s\n", pagerank_get_URL_i(&p, 0)); + printf("L'indice de l'URL du LIPN est %d\n", pagerank_find_indice_URL(&p, lipn)); + + pagerank_remove_URL(&p, aRetirer); + + pagerank_afficher(&p); + + pagerank_relier_URL(&p, google, youtube); + pagerank_relier_URL(&p, youtube, youtubeHistory); + pagerank_relier_URL(&p, youtube, youtubeSubs); + pagerank_relier_URL(&p, lipn, lipnA3); + pagerank_relier_URL(&p, lipn, lipnAOC); + pagerank_relier_URL(&p, lipn, lipnPresentation); + pagerank_relier_URL(&p, lipnPresentation, lipnA3); + pagerank_relier_URL(&p, lipnPresentation, lipnAOC); + pagerank_relier_URL(&p, fichierNico, google); + pagerank_afficher(&p); + + pagerank_ecrire_dot(&p, fichier1); + + printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); + + pagerank_delier_URL(&p, fichierNico, google); + + pagerank_ecrire_dot(&p, fichier2); + + printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); + + printf("Retirons maintenant \"%s\" du pagerank\n", google); + + pagerank_remove_URL(&p, google); + + pagerank_ecrire_dot(&p, fichier3); + pagerank_afficher(&p); + + pagerank_detruire(&p); + return EXIT_SUCCESS; +}