forked from menault/2026_TD3_DEV51_Qualite_Algo
Optimiser F6 avec un index direct par identifiant
This commit is contained in:
@@ -299,3 +299,17 @@ conservés comme dans les boucles initiales. Les **97 655 séries** de longueur
|
|||||||
1 à 7 à valeurs dans `[-2, 2]` sont comparées à la version cubique, sur la
|
1 à 7 à valeurs dans `[-2, 2]` sont comparées à la version cubique, sur la
|
||||||
somme et sur les deux bornes : elles couvrent notamment les zéros, les
|
somme et sur les deux bornes : elles couvrent notamment les zéros, les
|
||||||
égalités et les séries entièrement négatives.
|
égalités et les séries entièrement négatives.
|
||||||
|
|
||||||
|
### F6 — Index direct par identifiant
|
||||||
|
|
||||||
|
Les identifiants sont une permutation de `[0, n - 1]`. Un index de pointeurs
|
||||||
|
est construit en **`O(n)`** avant la boucle des requêtes. Chaque recherche
|
||||||
|
contrôle les bornes et renvoie `index_ids[id]` en **`O(1)`**, au lieu de
|
||||||
|
parcourir les transactions en `O(n)`. Le coût des `Q` requêtes, construction
|
||||||
|
comprise, devient **`O(n + Q)`**, avec `O(n)` de mémoire supplémentaire.
|
||||||
|
|
||||||
|
Les recherches ont toutes lieu avant le tri des transactions : un déplacement
|
||||||
|
des transactions imposerait de reconstruire l'index. F6 garde **M = 3** et
|
||||||
|
`indexer_par_id` a **M = 2**. Les tests comparent les pointeurs renvoyés
|
||||||
|
à une recherche linéaire sur des identifiants permutés pour les tailles
|
||||||
|
1 à 128, et vérifient les recherches hors bornes et dans un tableau vide.
|
||||||
|
|||||||
@@ -171,12 +171,18 @@ long meilleure_periode(const long *totaux, int nb_jours, int *debut, int *fin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* F6 : retrouve une transaction à partir de son id */
|
/* F6 : retrouve une transaction à partir de son id */
|
||||||
const Transaction *rechercher_par_id(const Transaction *t, int n, int id)
|
/* Les id forment une permutation de 0 à n - 1. Reconstruire après tout tri. */
|
||||||
|
void indexer_par_id(const Transaction *t, int n, const Transaction **index_ids)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
if (t[i].id == id)
|
index_ids[t[i].id] = &t[i];
|
||||||
return &t[i];
|
}
|
||||||
|
|
||||||
|
const Transaction *rechercher_par_id(const Transaction *const *index_ids, int n, int id)
|
||||||
|
{
|
||||||
|
if (id < 0 || id >= n)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
return index_ids[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* F7 : nombre de paires de transactions de montants opposés (a + b = 0) */
|
/* F7 : nombre de paires de transactions de montants opposés (a + b = 0) */
|
||||||
@@ -280,11 +286,13 @@ int main(void)
|
|||||||
rapport[0] = '\0';
|
rapport[0] = '\0';
|
||||||
|
|
||||||
/* recherches par id, dans l'ordre d'origine */
|
/* recherches par id, dans l'ordre d'origine */
|
||||||
|
static const Transaction *index_ids[NB_TRANSACTIONS];
|
||||||
|
indexer_par_id(t, NB_TRANSACTIONS, index_ids);
|
||||||
long somme_requetes = 0;
|
long somme_requetes = 0;
|
||||||
unsigned long etat = 12345;
|
unsigned long etat = 12345;
|
||||||
for (int q = 0; q < NB_REQUETES; q++) {
|
for (int q = 0; q < NB_REQUETES; q++) {
|
||||||
etat = etat * 1103515245UL + 12345UL;
|
etat = etat * 1103515245UL + 12345UL;
|
||||||
const Transaction *r = rechercher_par_id(t, NB_TRANSACTIONS, (int)((etat >> 8) % NB_TRANSACTIONS));
|
const Transaction *r = rechercher_par_id(index_ids, NB_TRANSACTIONS, (int)((etat >> 8) % NB_TRANSACTIONS));
|
||||||
if (r != NULL)
|
if (r != NULL)
|
||||||
somme_requetes += r->montant;
|
somme_requetes += r->montant;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,6 +154,29 @@ static void tester_periodes(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tester_recherches(void)
|
||||||
|
{
|
||||||
|
assert(rechercher_par_id(NULL, 0, 0) == NULL);
|
||||||
|
assert(rechercher_par_id(NULL, 0, -1) == NULL);
|
||||||
|
Transaction t[128];
|
||||||
|
const Transaction *index_ids[128];
|
||||||
|
for (int n = 1; n <= 128; n++) {
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
t[i] = (Transaction){n - 1 - i, i, i, i * 77 - 12};
|
||||||
|
indexer_par_id(t, n, index_ids);
|
||||||
|
for (int id = 0; id < n; id++) {
|
||||||
|
const Transaction *attendu = NULL;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
if (t[i].id == id)
|
||||||
|
attendu = &t[i];
|
||||||
|
assert(rechercher_par_id(index_ids, n, id) == attendu);
|
||||||
|
}
|
||||||
|
assert(rechercher_par_id(index_ids, n, -1) == NULL);
|
||||||
|
assert(rechercher_par_id(index_ids, n, n) == NULL);
|
||||||
|
assert(rechercher_par_id(index_ids, n, INT_MAX) == NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
tester_tri();
|
tester_tri();
|
||||||
@@ -161,6 +184,7 @@ int main(void)
|
|||||||
tester_totaux_clients();
|
tester_totaux_clients();
|
||||||
tester_totaux_jours();
|
tester_totaux_jours();
|
||||||
tester_periodes();
|
tester_periodes();
|
||||||
|
tester_recherches();
|
||||||
puts("Tests banque : OK");
|
puts("Tests banque : OK");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user