From 7390921cdc74ede435f93cc2d95bb5c84291bbe4 Mon Sep 17 00:00:00 2001 From: kpeglo Date: Mon, 26 Oct 2026 16:43:14 +0100 Subject: [PATCH] opti7 --- banque.c | 97 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 26 deletions(-) diff --git a/banque.c b/banque.c index 9735c9a..3478894 100644 --- a/banque.c +++ b/banque.c @@ -167,22 +167,81 @@ long meilleure_periode(const long *totaux, int nb_jours, int *debut, int *fin) return meilleur; } -/* F6 : retrouve une transaction à partir de son id en O(1) */ -const Transaction *rechercher_par_id(const Transaction *t, const int *index, int n, int id) +/* F6 : retrouve une transaction à partir de son id */ +const Transaction *rechercher_par_id(const Transaction *t, int n, int id) { - if (id < 0 || id >= n) - return NULL; - - return &t[index[id]]; + for (int i = 0; i < n; i++) + if (t[i].id == id) + return &t[i]; + return NULL; } -/* F7 : nombre de paires de transactions de montants opposés (a + b = 0) */ + +/* Comparaison de montants pour qsort */ +static int comparer_montants(const void *a, const void *b) +{ + long x = *(const long *)a; + long y = *(const long *)b; + if (x < y) return -1; + if (x > y) return 1; + return 0; +} + +/* F7 optimisée : compte les paires de montants opposés (a + b = 0) */ long nb_paires_opposees(const Transaction *t, int n) { - long nb = 0; + if (n < 2) + return 0; + + long *montants = malloc(n * sizeof(long)); + if (montants == NULL) { + /* En cas d'échec d'allocation, conserve un résultat correct. */ + long nb = 0; + for (int i = 0; i < n; i++) + for (int j = i + 1; j < n; j++) + if (t[i].montant + t[j].montant == 0) + nb++; + return nb; + } + for (int i = 0; i < n; i++) - for (int j = i + 1; j < n; j++) - if (t[i].montant + t[j].montant == 0) - nb++; + montants[i] = t[i].montant; + + qsort(montants, n, sizeof(long), comparer_montants); + + long nb = 0; + int gauche = 0; + int droite = n - 1; + + while (gauche < droite) { + long somme = montants[gauche] + montants[droite]; + + if (somme < 0) { + gauche++; + } else if (somme > 0) { + droite--; + } else if (montants[gauche] == montants[droite]) { + long nombre = droite - gauche + 1; + nb += nombre * (nombre - 1) / 2; + break; + } else { + long valeur_gauche = montants[gauche]; + long valeur_droite = montants[droite]; + long compte_gauche = 0; + long compte_droite = 0; + + while (gauche <= droite && montants[gauche] == valeur_gauche) { + compte_gauche++; + gauche++; + } + while (droite >= gauche && montants[droite] == valeur_droite) { + compte_droite++; + droite--; + } + nb += compte_gauche * compte_droite; + } + } + + free(montants); return nb; } @@ -271,21 +330,8 @@ unsigned long empreinte(const char *s) int main(void) { Transaction *t = generer_transactions(NB_TRANSACTIONS); - int *index = malloc(NB_TRANSACTIONS * sizeof(int)); char *rapport = malloc(1 << 20); char ligne[128]; - - if (t == NULL || index == NULL || rapport == NULL) { - fprintf(stderr, "Erreur d'allocation mémoire.\n"); - free(t); - free(index); - free(rapport); - return 1; - } - - for (int i = 0; i < NB_TRANSACTIONS; i++) - index[t[i].id] = i; - rapport[0] = '\0'; /* recherches par id, dans l'ordre d'origine */ @@ -293,7 +339,7 @@ int main(void) unsigned long etat = 12345; for (int q = 0; q < NB_REQUETES; q++) { etat = etat * 1103515245UL + 12345UL; - const Transaction *r = rechercher_par_id(t, index, NB_TRANSACTIONS, (int)((etat >> 8) % NB_TRANSACTIONS)); + const Transaction *r = rechercher_par_id(t, NB_TRANSACTIONS, (int)((etat >> 8) % NB_TRANSACTIONS)); if (r != NULL) somme_requetes += r->montant; } @@ -360,7 +406,6 @@ int main(void) printf("Empreinte : %016lx\n", empreinte(rapport)); free(rapport); - free(index); free(t); return 0; } \ No newline at end of file