Comparaison de StringList [Résolu/Fermé]

Messages postés
76
Date d'inscription
mardi 28 juin 2005
Dernière intervention
21 avril 2010
- - Dernière réponse : zwyx
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Dernière intervention
21 mars 2016
- 14 janv. 2010 à 20:59
Voila le sujet,
J'ai 2 fichiers textes que j'ai monter dans 2 TStringList différentes (ListeFichier1, ListeFichier2) avec environ 70000 lignes chacuns.
Chaque lignes de mes StringList sont composés d'un numéro (entier).
Je voudrais savoir avec mon programme si le numéro de la 1ere ligne de ListeFichier1 se trouve dans ListeFichier2, de la 2eme de ListeFichier1 se trouve dans ListeFichier2, de la 3eme... jusqu'a la derniere.
Si quelqu'un pouvais m'aider, se serais tres gentils.
Merci
Afficher la suite 

14 réponses

Meilleure réponse
Messages postés
121
Date d'inscription
jeudi 24 janvier 2002
Dernière intervention
13 avril 2010
3
Merci
for i := 0 to stringlist1.count - 1 do
for j := 0 to stringlist2.count - 1 do
if stringlist.strings[i] = stringlist2.strings[j] then
// egalité

Merci padsou 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de padsou
Messages postés
1651
Date d'inscription
samedi 10 juillet 2004
Dernière intervention
25 juillet 2014
3
Merci
salut,


la suppression des éléments d'une liste modifiant le propriete count tu aurais une erreur d'execution. il faut modifier la fonction:


for i := stringlist1.count - 1 downto 0do
for j := stringlist2.count - 1 downto do
if stringlist.strings[i] = stringlist2.strings[j] then
begin
stringlist1.delete(i); stringlist2.delete(j);
end;
bonne prog

Merci jlen100 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de jlen100
Messages postés
1651
Date d'inscription
samedi 10 juillet 2004
Dernière intervention
25 juillet 2014
3
Merci
on delete ListeFichier1 trop tot alors que l'on n'a pas terminé la seconde boucle et l'on compare ListeFichier2.Strings[j] à un élément qui n'existe si c'était le dernier élément de la liste on est hors limite plus il faut rajouter un marqueur



var flag:boolean;

flag:= false; // marqueur indiquant que l'on doit effacer un élélement dans ListeFichier1

For i : = ListeFichier1.count - 1 downto 0 do

begin
For j := ListeFichier2.count - 1 downto 0 do

begin

If ListeFichier1.Strings[i] = ListeFichier2.Strings[j] then
begin
ListeFichier2.delete(j);

flag:= true; //on positionne le marqueur
end ;

end;

if flag then ListeFichier1.delete(i); //si le marqueur est positionné on efface

flag: =false; //on réinitialisele marqueur

end;
je n'ai pas pu tester ce code mais en théorie ça marche

Merci jlen100 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de jlen100
Messages postés
76
Date d'inscription
mardi 28 juin 2005
Dernière intervention
21 avril 2010
0
Merci
Ok merci, c'est vraiment tout con en fait...
Commenter la réponse de Dezouille
Messages postés
1529
Date d'inscription
samedi 12 juin 2004
Dernière intervention
5 juillet 2010
0
Merci
Tu peux aussi faire :

if StringList1.Text = StringList2.Text then

[...]


@+

Nico { http://perso.wanadoo.fr/ni69/ }




<hr size ="2" width="100%">

N'oubliez pas de cliquer sur Réponse Acceptée lorsque la réponse vous convient !
Commenter la réponse de ni69
Messages postés
2
Date d'inscription
vendredi 7 mars 2003
Dernière intervention
4 octobre 2005
0
Merci
Une autre approche...

var n : integer;
for i := 0 to stringlist1.count - 1 do
n := stringlist2.IndexOf(stringlist1.strings[i]);
// if n <> -1 --> stringlist1.strings[i] correspond à stringlist2.string[n]
// if n = -1 --> stringlist1.strings[i] n'existe pas dans stringlist2

L'avantage de cette méthode est que tu ne dois pas parcourir à chaque fois stringlist2 (sur 70000 lignes cela peut faire une différence en temps de calcul).

@+
Commenter la réponse de MDUSE
Messages postés
1105
Date d'inscription
dimanche 1 août 2004
Dernière intervention
17 août 2008
0
Merci
Mais la fonciton IndexOf parcours elle même toute la liste: cela
revient au même, sauf que cela est fait internement (mais pas pus
rapidement). Par contre, ta méthode MDUSE, serait efficace sur une
THashedStringList disponible dans l'unité IniFiles.



En effet, la classe THashedStringList a en mémoire une liste de hashage
des chaines qui permet, en dépit d'un surcout (mais négligable) de
mémoire, d'améliorer les performances et cela d'autant plus que la
liste contient de chaines.



Attention: les performances ne sont augmentées que pour les fonction IndexOf() et IndexOfName().



Application de ce procédé à ton problème: ce code regarde si toutes les chaines de S1 sont contenues dans S2.

uses

IniFiles;



procedure TForm1.Button1Click(Sender: TObject);

var

S1, S2: THashedStringList;

i: Integer;

Good: Boolean;

begin

S1 : = THashedStringList.Create;

S2 := THashedStringList.Create;

try

S1.LoadFromFile('Fich 01.txt');

S2.LoadFromFile('Fich 02.txt');



{ Vérificaiton simpliste: il faut que la 2ème StringList contienne au moins

autant de chaines que la première. }

Good : = S2.Count >= S1.Count;



{ Si c'est le cas, on continue. }

if Good then

for i : = 0 to S1.Count -1 do

{ Test de chaque ligne. }

if S2.IndexOf(S1.Strings[i]) < 0 then

begin

Good := False;

Break;

end ;



{ Interpretation du résultat. }

if Good then

begin

// A faire si oui

end

else

begin

// A faire si non.

end;



finally

S1.Free;

S2.Free;

end; // try.

end;

<hr size ="2" width="100%">@ ++

Florent



PS: Valier les réponses si elles vous conviennent.


Si tu ne te plantes pas ......
tu ne poussera jamais
Commenter la réponse de florenth
Messages postés
76
Date d'inscription
mardi 28 juin 2005
Dernière intervention
21 avril 2010
0
Merci
En faite je viens de me rendre compte que mes TStringList ne sont pas trier. Je voudrais les trier dans l'ordre croissant. Quel est la syntaxe la plus simple?
Commenter la réponse de Dezouille
Messages postés
1651
Date d'inscription
samedi 10 juillet 2004
Dernière intervention
25 juillet 2014
0
Merci
salut,

tu mets la propriete sorted a true.

bonne prog
Commenter la réponse de jlen100
Messages postés
76
Date d'inscription
mardi 28 juin 2005
Dernière intervention
21 avril 2010
0
Merci
C'est bon, ça marche pas mal, mais il me reste encore un petit point à voir.
Une fois la recherche effectuer, si la condition me revoi "vrai", je voudrais supprimer les lignes trouver dans l'egalité, dans mes 2 stringlist, a mettre dans le "Then" de mon "If".
Commenter la réponse de Dezouille
Messages postés
76
Date d'inscription
mardi 28 juin 2005
Dernière intervention
21 avril 2010
0
Merci
Ok merci.
Effectivement j'avait une erreur d'exécution avec la fonction delete. C'était exactementça mon soucis.
Encore merci. Bonne prog à toi aussi
Commenter la réponse de Dezouille
Messages postés
76
Date d'inscription
mardi 28 juin 2005
Dernière intervention
21 avril 2010
0
Merci
La fonction de suppresion de fonctionne pas.
J'ai bien:
For i := ListeFichier1.count - 1 downto 0 do
For j := ListeFichier2.count - 1 downto 0 do
If ListeFichier1.Strings[i] = ListeFichier2.Strings[j] then
begin
ListeFichier1.delete(i);
ListeFichier2.delete(j);
end;

Lors de l'execution il me met l'eereur suivante:

Project Tri.exe raised exception class EStringListError with message 'List index out of bounds (70544)'. Process stopped. Use Step or Run to continue.

Je ne sais pas quoi faire
Commenter la réponse de Dezouille
Messages postés
1651
Date d'inscription
samedi 10 juillet 2004
Dernière intervention
25 juillet 2014
0
Merci
je crois savoir d'ou viens le problème:

si dans la seconde liste on delete 2 chaine ou plus et que l'on soit à
la fin de la 1ere liste i pointe au dela de la fin de la liste ce qui
provoque l'erreur indice hors limite.

voilà pour la cause; reste maintenant à trouver la solution . j'y jette un oeil ... ou peut-être même les deux.
Commenter la réponse de jlen100
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Dernière intervention
21 mars 2016
0
Merci
Bonjour à tous (4 ans après...), et bonne année,

Je cherche également à supprimer les doublons dans une StringList, et puisque l'on peut trier les chaînes, il suffit de comparer chaque élément avec son précédent (ou son suivant).

Voilà donc ce que je vous propose:
procedure MaClasse.SupprimerDoublonsDansListeTriee(var AMaListe: TStringList);
var
  iCompteur: Integer;
begin
  { on trie la liste }
  if not AMaListe.Sorted then
    AMaListe.Sort;

  { on parcourt la liste, si elle contient au moins 2 éléments }
  if AMaListe.Count > 1 then
  begin
    { on commence le parcourt par le 2è élément }
    iCompteur := 1;
    while iCompteur < AMaListe.Count do
      { on compare l'élément courant avec le précédent }
      if AMaListe.Strings[iCompteur] = AMaListe.Strings[iCompteur-1] then
        AMaListe.Delete(iCompteur)
      else
        Inc(iCompteur);
  end;
end;

Le parcourt de la liste avec un while permet de ne jamais aller au delà de la liste, même quand on en supprime des éléments.

Cordialement
Commenter la réponse de zwyx

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.