Dezouille
Messages postés75Date d'inscriptionmardi 28 juin 2005StatutMembreDernière intervention21 avril 2010
-
16 août 2005 à 09:40
Dezouille
Messages postés75Date d'inscriptionmardi 28 juin 2005StatutMembreDernière intervention21 avril 2010
-
16 août 2005 à 15:08
Bonjour,
J'aimerais comparer les lignes de deux fichiers text. Mes fichiers possedes des lignes avec dedans un numéro de factures. Chaque fichier possede plus de 10000 lignes. En faites je voudrais verifier si les numéros de factures du premier fichier text se trouve dans le deuxieme, si les numeros du 2eme se trouve dans le premier, et si dans le deuxieme il n'y a pas de doublons. Je ne sais pas si j'ai bien expliqué.
Merci de votre aide.
neodelphi
Messages postés442Date d'inscriptionjeudi 4 avril 2002StatutMembreDernière intervention11 août 2008 16 août 2005 à 10:59
Oubli pas de creer les stringlist:
list1 := TStringList.Create();
Euh sinon les "°" il accepte le compilo ? Et si le fichier contiend plus de 10000 lignes ça risque pas de plomber la mémoire de les charger dans un stringlist ? il devrait etre possible de faire une lecture directement depuis le fichier, mais je croit que la méthode est légèrement plus compliquée.
Dezouille
Messages postés75Date d'inscriptionmardi 28 juin 2005StatutMembreDernière intervention21 avril 2010 16 août 2005 à 10:58
Merci pour ta reponse, en faite, si je comprend bien, on balaye a chaque fois toute la liste 2, tu me corrige si je me trompe. Car les listes ne sont pas trier. Se ne serais pas mieux de trier les liste sur les numeros de facture? J'aimerais que mon programme fasse une verification le plus rapidement possible.
Dezouille
Messages postés75Date d'inscriptionmardi 28 juin 2005StatutMembreDernière intervention21 avril 2010 16 août 2005 à 11:11
Je suis d'accord avec Neodelphi, je pense qu'il faudrais mieux faire un lecture direct, mais là je ne voit pas tellement comment faire, si quelqun pouvait m'aider la dessus, se serait gentil, merci.
Vous n’avez pas trouvé la réponse que vous recherchez ?
neodelphi
Messages postés442Date d'inscriptionjeudi 4 avril 2002StatutMembreDernière intervention11 août 2008 16 août 2005 à 11:16
Je ne sais plus comment on fait, mais je pense que tu peut rechercher du coté des TFileStream (pas les TMemoryStream qui chargent en mémoire le contenu du fichier, ce que tu veux éviter).
Recherche sinon des sources sur le site je pense qu'il y en a pas mal.
voir exemple
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201412 16 août 2005 à 12:08
il y a une solution pour réduire la recherche au lieu d'utiliser une
variable string on peut utiliser une variable record et tu utilise des
pointeurs
type :
Spointeur:^Ppointeur;
Ppointeur:
record
numfac:string;
numligne:integer;
end;
var Plist2:Spoint;
dans la creation de la liste tu fais:
i:=0;// premier enregistrement;
whille not eof(F2) do
begin
new(Plist2);//tu crée une entrée;
readln(F2,buffer2);
la tu extrait tes N° -->
with Plist2 do
begin
numligne:=i;// tu mémorises la ligne;
numfac:=N°;
end;
//tu les ajoutes à list1:
list1.add(Plist2);
end;
ensuite quand tu as fais la recherche avant de sortir du traitement tu fais
dispose(Plist2);// pour liberer la memoire;
list1.delete(i);// tu supprimes l'entrée et tu diminue la longueur de la liste attention tu ne peux liberer les entrees que tu as parcouru toute la liste il faudra donc mémoriser les entree a supprimer
ainsi la liste est réduite aux seules lignes qui n'ont pas été traitées.
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201412 16 août 2005 à 14:24
c'est encore moi,
après avoir regardé j'ai trouvé le moyen d'utiliser indexof qui renvoie la prmier occurence trouvée
dans le recherche tu peux faire
while list2.indexof(N°Fac)<>-1 do
begin
j:= list2.indexof(N°Fac);
Plist2:=list2[i];//nota j'avais oublie l'affectattion: pas bien!!
if no t present then
begin
present: =true ;traitement de l'entree (tu as le N° de ligne dans Plist2^.numligne)
end else traitement du doublon;
dispose(Plist2);// pour liberer la memoire;
list1.delete(j);// tu supprimes l'entrée et tu diminues la longueur de la liste
end;
le programme parcourt ainsi la liste jusqu'à la fin et supprime les
occurences au fur et à mesure. inconvénient il reprend le test depuis
le début (bien que ce soit trasparent le traitement risque d'etre plus
long.
également dans la constitution de la liste j'ai oublié d'incrementer i qui restera à 0: pas facile de retrouver le N° de ligne!!!
et dans with Plist2^ sinon le compilateur doit renvoyer une erreur decidement ce n'est pas mon jour!!
pour info sur un PC cadencé entre 2 et 3GHz le temps de traitement pour
10000 entrée devrait se situer au alentour de 10s non compris le
traitement de l'info (~10ns par test) pour la derniere solution cela
dvrait tourner au alentour de 15 a 20s
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201412 16 août 2005 à 14:48
tu peux encore améliorer la performance de l'ensemble en vérifiant s'il y a des doublons à la création de lits2 tu fais :
if list2.indexof(N°)<>-1 then traitement du doublon;
dans ce cas le traitement ce réduira a
while not eof (F1)do// on recherche le n° de facture
begin
readln(F1,buffer1)
N°Fac:= copy (buffer1);
j: =list2.indexof(N°Fac); // recherche de l'entrée
Plist2: = list2[i];
if j =-1 then traitement pas de facture en liste2
else
begin
traitement;
dispose(Plist2);// pour liberer la memoire;
list1.delete(j);// tu supprimes l'entrée et tu diminues la longueur de la liste
end;
end;
En séparant ainsi les 2 traitements on gagne d'une part en clarté et
d'autre part en efficacité psuique la liste à traitée ne contient plus
que des données valides