Tri de TDateTime et conversion de LongInt en Double
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 :
Code:
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; |
Mes types et variables :
Code:
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'; |
Chargement de la StringList et initialisation du tableau :
Code:
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; |
La procédure appelant la fonction de tri :
Code:
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; |
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
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 :mrgreen: