Compter les valeurs... [Résolu]

cs_fermat 2 Messages postés vendredi 26 septembre 2003Date d'inscription 8 avril 2007 Dernière intervention - 8 avril 2007 à 19:12 - Dernière réponse : jelume 122 Messages postés mardi 3 avril 2007Date d'inscription 15 novembre 2007 Dernière intervention
- 10 avril 2007 à 09:38
Bonjour,


J'ai un fichier txt.composé de :


10 lignes , comportant 20 valeurs (par ligne), séparées par
un point virgule.


J’ai chargé ce fichier dans un mémo.

Je souhaite établir un tableau dans un second 
mémo , qui affichera le nombre de sorties de chacune d'elles.

Exemple:[408....présent...12 fois]

             
[124....présent...56 fois]


Ma question:

Quelle procédure de calcul faut-il écrire pour obtenir l'affichage dans le 2nd
mémo


Merci de votre aide.
Afficher la suite 

Votre réponse

5 réponses

Meilleure réponse
jelume 122 Messages postés mardi 3 avril 2007Date d'inscription 15 novembre 2007 Dernière intervention - 8 avril 2007 à 22:02
3
Merci
une autre solution pas très optimisée non plus, mais bon, comme dit japee, il faut encourager les vocations :-)


procedure CompterValeurs(Source: TStrings; Destination: TStrings);
type
  TCompte = record
    Valeur          : Integer;
    NombreOccurences: Integer;
  end;
  TComptes = array of TCompte;


var
  I, J, K: Integer;
  Lst: TStringList;
  Comptes: TComptes;


  function IndiceValeurDansTableau(Value: Integer):Integer;
  var
    I: Integer;
  begin
    Result := -1;
    for I := Low(Comptes) to High(Comptes) do
    begin
      if Value = Comptes[I].Valeur then
      begin
        Result := I;
        Break;
      end;
    end;
  end;


begin


  Destination.Clear;


  // Stockage temporaire pour chaque ligne
  Lst := TStringList.Create;
  for I := 0 to Pred(Source.Count) do  // pour chaque ligne de la source
  begin


    Lst.Clear;
    // Créer un StringList contenant les valeurs séparées par un ;
    ExtractStrings([';'], [' '], PChar(Source[I]), Lst);
    // Trie la liste
    Lst.Sort;


    for J := 0 to Pred(Lst.Count) do
    begin


      // Cherche si la valeur est déjà compteé au moins une fois ou plus
      K := IndiceValeurDansTableau(StrToInt(Lst[J]));


      // Si -1 renvoyé, n'existe pas encore dans le tableau
      if K = -1 then
      begin
        // Ajoute un élément au tableau
        SetLength(Comptes, Length(Comptes) + 1);
        Comptes[High(Comptes)].Valeur           := StrToInt(Lst[J]);
        Comptes[High(Comptes)].NombreOccurences := 1;
      end
      else
        // Incrémente le nombre de valeurs
        Inc(Comptes[K].NombreOccurences);


    end;


  end;
  Lst.Free;


  // A partir de là, pas compliqué
  for I := Low(Comptes) to High(Comptes) do
    Destination.Add(format('%d trouvé %d fois', [Comptes[I].Valeur, Comptes[I].NombreOccurences]));


  Finalize(Comptes);


end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  CompterValeurs(memo1.lines, memo2.lines);
end;


 

Merci jelume 3

codes-sources a aidé 82 internautes ce mois-ci

Commenter la réponse de jelume
cptpingu 3789 Messages postés dimanche 12 décembre 2004Date d'inscription 25 mai 2018 Dernière intervention - 8 avril 2007 à 20:39
0
Merci
Tu avait deja pose cette question ici:
http://www.delphifr.com/infomsg_COMPTABILISER-VALEURS-FICHIER-TXT_913762.aspx#3

Ensuite, cherche un peu, ce que tu demandes est très simple. On ne va pas te faire chacune des étapes de ton code.
Commenter la réponse de cptpingu
japee 1792 Messages postés vendredi 27 décembre 2002Date d'inscription 12 novembre 2016 Dernière intervention - 8 avril 2007 à 21:41
0
Merci
Salut,

CptPingu a tout à fait raison.

Mais bon, à titre d'encouragement, voici un morceau de code qui fait ce que tu demandes.
Attention, bien que fonctionnel, il mérite d'être optimisé.
Je le mets à ta disposition afin que tu puisses l'étudier.
Si tu a des questions n'hésite pas.

procedure SortAndCountDatas(const StringsA, StringsB: TStrings);
var
  i: Integer;
  StringList: TStringList;
  Tmp: string;
  N: Integer;
begin
  with StringsA do
    for i := 0 to Count -1 do
    begin
      Strings[i] := StringReplace(Strings[i], ';', ',', [rfReplaceAll]);
    end;
  StringList := TStringList.Create;
  try
    StringList.CommaText := StringsA.Text;
    StringList.Sorted := True;
    Form1.Memo3.Text := StringList.Text;
    StringsB.Clear;
    StringsB.BeginUpdate;
    N := 1;
    for i := 0 to StringList.Count -1 do
    begin
      Tmp := StringList[i];
      if (i < StringList.Count -1) and (StringList[i+1] = Tmp) then
        Inc(N)
      else
      begin
        StringsB.Add(Format('%s trouvé %d fois',[Tmp, N]));
        N := 1;
      end;
    end;
    StringsB.EndUpdate;
  finally
    StringList.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.LoadFromFile('tonfichier.txt');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  SortAndCountDatas(Memo1.Lines, Memo2.Lines);
end;

Bonne prog'
Commenter la réponse de japee
japee 1792 Messages postés vendredi 27 décembre 2002Date d'inscription 12 novembre 2016 Dernière intervention - 10 avril 2007 à 00:27
0
Merci
Bonsoir,

Je vois que la méthode de jelume a eu plus de succès que la mienne...


Je ne suis pas sûr d'arriver à survivre à ça...


Voici néanmoins une évolution de la mienne.

La fonction ne modifie plus le contenu du premier TStrings, ce qu'elle
n'avait pas à faire puisque ça ne lui était pas demandé, non mais...

procedure SortAndCountDatas(const StringsA, StringsB: TStrings);

var

  i: Integer;

  Tmp: string;

  N: Integer;

begin

  with TStringList.Create do

  try

    Text := StringsA.Text;

    Text := StringReplace(Text, ';', ',', [rfReplaceAll]);

    CommaText := Text;

    Sort;

    StringsB.Clear;

    StringsB.BeginUpdate;

    N := 1;

    for i := 0 to Count -1 do

    begin

      Tmp := Strings[i];

      if (i < Count -1) and (Strings[i+1] = Tmp) then

        Inc(N)

      else

      begin

        StringsB.Add(Format('%s trouvé %d fois', [Tmp, N]));

        N := 1;

      end;

    end;

    StringsB.EndUpdate;

  finally

    Free;

  end;

end;


Bonne nuit les petits, pom pom pom pom, pom pom pom, pom pom...
Commenter la réponse de japee
jelume 122 Messages postés mardi 3 avril 2007Date d'inscription 15 novembre 2007 Dernière intervention - 10 avril 2007 à 09:38
0
Merci
lol ... désolé japee ... pas taper ...

En fait, je pourrais aussi optimiser la mienne en utilisant une chaine de carctères construite à partir du TStringList original. En remplaçant tous les caratères sLineBreak par un ; et en construisant une liste unique à partir de la propriété text en utilisant extractstrings. Ca évite la double boucle.
Mais j'aime bien aussi ta façon de faire, qui évite d'utiliser un tableau (qui n'a d'autre but que de clarifier le code pour un novice).

Bonne journée

J-Luc
Commenter la réponse de jelume

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.