Bonjour à tous
Je veux trier par date une liste de fichiers. J'ai utilisé la fonction ci-dessous du site de M. Bardou. Elle trie des LongInt, pas des "double". C'est là le hic.
Url de la fonction.
Pour infos, voici la fonction à peine modifiée :
Mes types et variables :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 Var Les_Chiffres : array[0..1000000] of longint; Procedure Tri_Nimportequoi(Longueur_Tab : integer); // Modifié par moi : j'ai ajouté ce paramètre Var s, sj, sl, sr, j,S1: LongInt; // les compteurs intermediaires du tri Code: Longint; // Clef de recherche Resa_Chiffre: LongInt; // Utiliser pour les permutation doit etre du mÍme type que la donnée triée St: Array[0..100, 0..1] Of LongInt; // Table qui remplace la recursivitÈ et amÈliore CONSIDERABLEMENT les performances // le dimensionnement ‡ 100 correspond au nombre maximal d'appel en recursivitÈ // normalement 10 devraient suffir mais avec 100 on doit pouvoir trier quelque milliards d'infos... Begin S := 1; // IMPORTANT je ne trie pas l'ÈlÈment ZERO st[S, 0] := 1; // Il suffit normalement de metrre S ‡ zero pour le trier st[S, 1] := Longueur_Tab; // Nombre d'elements à trier. Modifié par moi : le paramètre Repeat sl := st[S, 0]; // Sauvegarde des offsets pour la recursivitÈ sr := st[S, 1]; S := pred(S); Repeat j := sl; // le quick sort trie le fichier par morceau de plus en plus grands sj := sr; S1 := (sl + sr) Div 2; // on divise le nombre d'elements choisi par deux Code := Les_Chiffres[S1]; // On mÈmorise le criter de tri de l'elemnt actif (plus de clarte dans les tests ‡ suivre Repeat While (Les_Chiffres[J] < Code) Do // Partant du debut de la portion selectionnée on, recherche le p j := j + 1; // premier element plus grand dans cet interval While (Code < Les_Chiffres[Sj]) Do // maintenant on recherchje le plus petit partant de la fin SJ := Sj - 1; If j <= sj Then // quand on a trouve on permute avec resa_Chiffre Begin // l'autre concept du quick sort est que plus la permutation est Resa_Chiffre := Les_Chiffres[Sj]; // lointaine plus elle est efficace: il vaut mieux permuter le premier Les_Chiffres[Sj] := Les_Chiffres[j]; // avec le dernier que le premier avec le second Les_Chiffres[j] := Resa_Chiffre; // il a plus de chance d'Ítre ‡ sa place j := Succ(J); // Je laisse les mathÈmaticiens le dÈmontrer.... sj := Pred(sj); // on retrecie la portion de recherche jusqu'a son arrivÈe ‡ 0 elements End; Until j > sj; If j < sr Then // Et c'est la qu'on recursive en se servant de la table Begin S := Succ(S); St[S, 0] := j; St[S, 1] := sr; End; sr := sj; until sl >= sr; Until S < 1; // et la c'est FINI End;
Chargement de la StringList et initialisation du tableau :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Type Struct_Infos_F = record Nom_Cplt_F : string; Der_Acces : TDateTime; End; Var Tab_F : array of Struct_Infos_F; Idx_Tab : integer; Lst_F : TStringList; Nom_F_Liste : string = 'RESULTAT FINAL.LOG';
La procédure appelant la fonction de tri :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 Procedure Charger_Lst_F; Var i : integer; begin Lst_F := TStringList.Create; Lst_F.LoadFromFile(Nom_F_Liste); SetLength(Tab_F, Lst_F.Count); for i := 0 to Lst_F.Count -1 do begin Tab_F[i].Nom_Cplt_F := Lst_F.Strings[i]; Tab_F[i].Der_Acces := TimeModificationFichier(Lst_F.Strings[i]); end; end;
Le tri n'est pas correct, forcément. La fonction de tri opère sur des LongInt, pas des Double. Or, TDateTime est un Double, non ? Et même avec les
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 Procedure Trier_Dates; Var i : integer; Tab_Dates : array of TDateTime; Entier_Long : Variant; // Variant ou LongInt, même résultat Lst_ICI : TStringList; Num_F : integer; Nom_F : string; begin Lst_ICI := TStringLIst.Create; Lst_ICI.Add('FICHIERS TRIES PAR DATES'); Lst_ICI.Add('------------------------'); for i := 0 to Lst_F.Count -1 do begin Entier_Long := Tab_F[i].Der_Acces; Les_Chiffres[i] := Entier_Long; end; Tri_Nimportequoi_Bis(Lst_F.Count); SetLength(Tab_Dates, Lst_F.Count); for i := 0 to Lst_F.Count -1 do begin Idx_Tab := i; Num_F := Idx_Tab; // N° de F pointé ds Tab_Dates Nom_F := Tab_F[Idx_Tab].Nom_Cplt_F; // Nom du F pointé ds Tab_F[Idx_Tab] Lst_ICI.Add(Nom_F + #13+#10 + 'DATE : ' + DateToStr(Tab_F[Num_F].Der_Acces)); end; Lst_ICI.SaveToFile('Z-LISTE TRIEE.TMP'); Lst_ICI.Free; SetLength(Tab_Dates, 0); end;
Que feriez-vous ?
1 - Modifier la fonction elle-même pour la rendre compatible avec des Double ?
2 - Mieux : convertir en Double les LongInt que sont les TDateTime ? Mais là, je bute. Ce devrait être possible, puisqu'un LongInt est plus court qu'un Double ? L'opération inverse, non.
Je ne sais pas si j'ai été très clair![]()
Partager