Main #4

Open
Karl Framery wants to merge 5 commits from framery/2026_TD3_DEV51_Qualite_Algo:main into main
2 changed files with 67 additions and 28 deletions
BIN
View File
Binary file not shown.
+67 -28
View File
@@ -88,28 +88,29 @@ void trier_par_montant(Transaction *t, int n)
/* F2 : nombre de clients ayant au moins une transaction */
int nb_clients_distincts(const Transaction *t, int n)
{
int clients_vus[NB_CLIENTS] = {0};
int nb = 0;
for (int i = 0; i < n; i++) {
int client = t[i].client;
if (!clients_vus[client]) {
clients_vus[client] = 1;
nb++;
int deja_vu = 0;
for (int j = 0; j < i; j++) {
if (t[j].client == t[i].client) {
deja_vu = 1;
break;
}
}
if (!deja_vu)
nb++;
}
return nb;
}
/* F3 : solde total de chaque client */
/* F3 : solde total de chaque client en O(n + c) */
void total_par_client(const Transaction *t, int n, long *totaux)
{
for (int c = 0; c < NB_CLIENTS; c++) {
totaux[c] = 0;
for (int i = 0; i < n; i++)
if (t[i].client == c)
totaux[c] += t[i].montant;
}
for (int i = 0; i < n; i++) {
totaux[t[i].client] += t[i].montant;
}
}
@@ -118,30 +119,36 @@ void total_par_jour(const Transaction *t, int n, long *totaux)
{
for (int j = 0; j < NB_JOURS; j++) {
totaux[j] = 0;
for (int i = 0; i < n; i++)
if (t[i].jour == j)
totaux[j] += t[i].montant;
}
for (int i = 0; i < n; i++)
totaux[t[i].jour] += t[i].montant;
}
/* F5 : période de jours consécutifs dont la somme des soldes est maximale */
/* F5 : période de jours consécutifs dont la somme des soldes est maximale en O(J) */
long meilleure_periode(const long *totaux, int nb_jours, int *debut, int *fin)
{
long meilleur = totaux[0];
*debut = 0;
*fin = 0;
for (int i = 0; i < nb_jours; i++) {
for (int j = i; j < nb_jours; j++) {
long somme = 0;
for (int k = i; k <= j; k++)
somme += totaux[k];
if (somme > meilleur) {
meilleur = somme;
*debut = i;
*fin = j;
}
long somme_courante = totaux[0];
int debut_courant = 0;
for (int j = 1; j < nb_jours; j++) {
if (somme_courante < 0) {
somme_courante = totaux[j];
debut_courant = j;
} else {
somme_courante += totaux[j];
}
if (somme_courante > meilleur) {
meilleur = somme_courante;
*debut = debut_courant;
*fin = j;
}
}
return meilleur;
}
@@ -155,13 +162,45 @@ const Transaction *rechercher_par_id(const Transaction *t, int n, int id)
}
/* F7 : nombre de paires de transactions de montants opposés (a + b = 0) */
static int cmp_long(const void *a, const void *b)
{
long x = *(const long *)a;
long y = *(const long *)b;
return (x > y) - (x < y);
}
long nb_paires_opposees(const Transaction *t, int n)
{
/* 1. Copier et trier les montants : O(n log n) */
long *m = malloc(n * sizeof(long));
for (int i = 0; i < n; i++) {
m[i] = t[i].montant;
}
qsort(m, n, sizeof(long), cmp_long);
/* 2. Deux pointeurs : O(n) au lieu de O(n²) */
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)
int g = 0, d = n - 1;
while (g < d) {
long somme = m[g] + m[d];
if (somme < 0) {
g++;
} else if (somme > 0) {
d--;
} else {
/* somme == 0 : on compte tous les m[d] identiques en face de m[g] */
for (int k = d; k > g && m[k] == m[d]; k--) {
nb++;
}
g++; /* Puis on passe simplement au m[g] suivant ! */
}
}
free(m);
return nb;
}