Comparaison de StringList [Résolu/Fermé]

Dezouille 76 Messages postés mardi 28 juin 2005Date d'inscription 21 avril 2010 Dernière intervention - 19 sept. 2005 à 11:06 - Dernière réponse : zwyx 152 Messages postés jeudi 22 novembre 2007Date d'inscription 21 mars 2016 Dernière intervention
- 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
padsou 121 Messages postés jeudi 24 janvier 2002Date d'inscription 13 avril 2010 Dernière intervention - 19 sept. 2005 à 11:41
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

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Commenter la réponse de padsou
Meilleure réponse
jlen100 1651 Messages postés samedi 10 juillet 2004Date d'inscription 25 juillet 2014 Dernière intervention - 21 sept. 2005 à 09:28
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

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Commenter la réponse de jlen100
Meilleure réponse
jlen100 1651 Messages postés samedi 10 juillet 2004Date d'inscription 25 juillet 2014 Dernière intervention - 22 sept. 2005 à 15:06
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

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Commenter la réponse de jlen100
Dezouille 76 Messages postés mardi 28 juin 2005Date d'inscription 21 avril 2010 Dernière intervention - 19 sept. 2005 à 11:45
0
Merci
Ok merci, c'est vraiment tout con en fait...
Commenter la réponse de Dezouille
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 19 sept. 2005 à 11:52
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
MDUSE 2 Messages postés vendredi 7 mars 2003Date d'inscription 4 octobre 2005 Dernière intervention - 19 sept. 2005 à 17:18
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
florenth 1105 Messages postés dimanche 1 août 2004Date d'inscription 17 août 2008 Dernière intervention - 19 sept. 2005 à 21:05
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
Dezouille 76 Messages postés mardi 28 juin 2005Date d'inscription 21 avril 2010 Dernière intervention - 20 sept. 2005 à 11:45
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
jlen100 1651 Messages postés samedi 10 juillet 2004Date d'inscription 25 juillet 2014 Dernière intervention - 20 sept. 2005 à 12:22
0
Merci
salut,

tu mets la propriete sorted a true.

bonne prog
Commenter la réponse de jlen100
Dezouille 76 Messages postés mardi 28 juin 2005Date d'inscription 21 avril 2010 Dernière intervention - 21 sept. 2005 à 08:21
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
Dezouille 76 Messages postés mardi 28 juin 2005Date d'inscription 21 avril 2010 Dernière intervention - 21 sept. 2005 à 09:48
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
Dezouille 76 Messages postés mardi 28 juin 2005Date d'inscription 21 avril 2010 Dernière intervention - 22 sept. 2005 à 10:05
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
jlen100 1651 Messages postés samedi 10 juillet 2004Date d'inscription 25 juillet 2014 Dernière intervention - 22 sept. 2005 à 13:49
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
zwyx 152 Messages postés jeudi 22 novembre 2007Date d'inscription 21 mars 2016 Dernière intervention - 14 janv. 2010 à 20:59
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.