IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Mélanger / mixer / Shuffle un Tlistbox ou array


Sujet :

Delphi

  1. #1
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut Mélanger / mixer / Shuffle un Tlistbox ou array
    salut

    je cherchais à très bien mélanger un Tlistbox ou un array (ils contiendront des nombres de 1 à 60)

    j'ai cherché sur le forum, et les morceaux de code trouvés ne fonctionnent pas correctement ou alors le mélange n'est pas efficace

    sur delphi about ou je trouve toujours tout, j'ai trouvé un code qui me semblait intéressant :

    http://delphi.about.com/cs/adptips20...ltip1003_4.htm

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    Place a TButton (Button1) and a TListBox (ListBox1) and try:
     
    ~~~~~~~~~~~~~~~~~~~~~~~~~
    procedure Shuffle(
       var aArray;
       aItemCount: Integer;
       aItemSize: Integer) ;
    var
       Inx: Integer;
       RandInx: Integer;
       SwapItem: PByteArray;
       A: TByteArray absolute aArray;
    begin
       if (aItemCount > 1) then
       begin
         GetMem(SwapItem, aItemSize) ;
         try
           for Inx := 0 to (aItemCount - 2) do
           begin
             RandInx := Random(aItemCount - Inx) ;
             Move(A[Inx * aItemSize], SwapItem^, aItemSize) ;
             Move(A[RandInx * aItemSize],
                  A[Inx * aItemSize], aItemSize) ;
             Move(SwapItem^, A[RandInx * aItemSize],
                  aItemSize) ;
           end;
         finally
           FreeMem(SwapItem, aItemSize) ;
         end;
       end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject) ;
    var
       a: array[1..54] of Integer;
       i: Shortint;
    begin
       Randomize;
       for i := Low(a) to High(a) do a := i;
       Shuffle(a, High(a), SizeOf(Integer)) ;
       ListBox1.Clear;
       for i := 1 to High(a) - 1 do
         ListBox1.Items.Add(IntToStr(a)) ;
    end;
    ~~~~~~~~~~~~~~~~~~~~~~~~~
    mais ça ne fonctionne pas !

    j'ai les messages d'erreur :

    [Erreur] Unit1.pas(66): Types incompatibles : 'Array' et 'Shortint'
    [Erreur] Unit1.pas(70): Aucune version surchargée de 'IntToStr' ne peut être appelée avec ces arguments


    donc voilà j'aimerais votre aide pou faire fonctionner ce code ou alors si vous avez une autre solution? il me faut quelque chose qui mélange bien ^^

    merci

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    J'avais trouvé ça il y a un moment, je ne sais plus où...:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure Shuffle(var Tableau: TIntegerArray);
    var
      i1, i2, iSwap:Integer;
    begin
      for i1:= High(Tableau) downto 1 do begin
        { Get a random card in the range of those that have not yet been shuffled }
        i2 := Random(i1 + 1); { i2 = random position ( <= i1) }
        { Exchange card in position "i1" with random position }
        iSwap := Tableau[i1];
        Tableau[i1] := Tableau[i2];
        Tableau[i2] := iSwap;
      end;
    end;
    Par contre le i2 := Random(i1 + 1) m'étonne, j'aurais plutôt vu Random(i1)...

  3. #3
    Membre chevronné

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 290
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2002
    Messages : 1 290
    Points : 1 941
    Points
    1 941
    Par défaut
    Pour ton erreur de compilation, il suffit de lire le message et d'aller voir les lignes concernées (66 et 70)...

    donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       for i := Low(a) to High(a) do a := i;
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       for i := Low(a) to High(a) do a[i] := i;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
         ListBox1.Items.Add(IntToStr(a)) ;
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
         ListBox1.Items.Add(IntToStr(a[i])) ;

  4. #4
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut
    merci à tous les 2

    GoustiFruit ton code ne fonctionne pas

    Linkin c'est ok et j'aimerais continuer avce ce code ...

    mais déjà je tiens à dire que je trouve bizarre que sur ce site il y ait une erreur de ce genre ...

    enfin bref, ça fonctionne, mais selon moi, pas assez mélangé ...

    on retrouve souvent des 26-27 ou 30-31

    ça arrive trop souvent

    vous avez une idée pour compléter ce code pour faire un mélange encore plus poussé ?

  5. #5
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    tu as du oublier le randomize


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure Shuffle(var Tableau: TIntegerArray);
    var
      i1, i2, iSwap:Integer;
    begin
      randomize;
      for i1:= High(Tableau) downto succ(low(Tableau)) do 
      begin
        i2 := Random(i1)+ 1;
        iSwap := Tableau[i1];
        Tableau[i1] := Tableau[i2];
        Tableau[i2] := iSwap;
      end;
    end;

    ou alors peut etre ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //randomize position of list elements
    procedure Shuffle(list : TList) ;
    var
      randomIndex: integer;
      cnt: integer;
    begin
      Randomize;
      for cnt := 0 to pred(list.Count) do
      begin
        randomIndex := Random(-cnt + list.Count) ;
        list.Exchange(cnt, cnt + randomIndex) ;
      end;
    end;
    @+ Phil

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 874
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    on retrouve souvent des 26-27 ou 30-31

    ça arrive trop souvent

    vous avez une idée pour compléter ce code pour faire un mélange encore plus poussé ?
    le hasard n'a jamais interdit des bribes de suite (ni même la suite 1..60 !)

    au passage, un ch'ti code qui fonctionne sur un TList

  7. #7
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    en fait a priori tu n'as pas compris le code
    celui-ci ne sert qu'a mélanger des élément existant il ne crée aucune valeur

    @+ Phil

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 874
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    @ anapurna : le code ne comprend que des échanges d'indices au hasard (appels à Random), et donc rien n'interdit de retrouver des suites d'indices or pour l'exemple, les indices sont chargés dans le tableau de test comme éléments, CQFD...
    Le code ne contenant pas de tests sur le contenu (ou l'indice avant mélange), rien ne peut empêcher des bribes du tableau initial de se retrouver dans le tableau final.
    Style battre un jeu de cartes...

  9. #9
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    je ne sais pas comment tu fait tes test mais a mon avis tu as un sérieux bug

    voici un test simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    52
    53
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        StringGrid1: TStringGrid;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        aTableau: TIntegerDynArray;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure Shuffle(var Tableau: TIntegerDynArray);
    var
      i1, i2, iSwap:Integer;
    begin
      randomize;
      for i1:= High(Tableau) downto succ(low(Tableau)) do
      begin
        i2 := Random(i1)+ 1;
        iSwap := Tableau[i1];
        Tableau[i1] := Tableau[i2];
        Tableau[i2] := iSwap;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
     len,i1 : integer;
    begin
      randomize;
      len := Round(Random(1000));
      setlength(aTableau,len);
      for i1:= low(aTableau) to High(aTableau) do
        aTableau[i1] := i1;
     
      Shuffle(aTableau);
      StringGrid1.RowCount :=High(aTableau);
      StringGrid1.ColCount := 3;
      for i1:= low(aTableau) to High(aTableau) do
      begin
        StringGrid1.Cells[1,i1] := IntToStr(i1) ;
        StringGrid1.Cells[2,i1] := IntToStr(aTableau[i1]) ;
      end;
    end;

  10. #10
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut
    anapurna et tourlourou merci totu d'abord pour votre aide, mais vous n'êtes pas allé trop loin ? lol

    anapurna je n'arrive pas à compiler ta source TIntegerDynArray ?

    à la base, j'ai un array of integer rangé de 1 à 60 et j'aimerais qu'il soit mélanger tout simplement

  11. #11
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 874
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    mais vous n'êtes pas allé trop loin ?
    tu sais, c'était fin 2008 : on devait être fatigués ! remarque, aujourd'hui...

    à la base, j'ai un array of integer rangé de 1 à 60 et j'aimerais qu'il soit mélangé tout simplement
    le code d'anapurna fonctionne parfaitement (déclare type TIntegerDynArray=array of integer

    et s'il arrive des "suites" comme 19,18 ou 51,52 c'est non seulement normal, mais souhaitable si ça doit être mélangé au hasard.

    ne pas vouloir que ça se produise revient à restreindre le hasard et nécessite je pense un codage hyperlourd

  12. #12
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Attention !

    Il ne faut surtout pas mettre Randomize dans la fonction de mélange. Il faut appeler cette procédure une et une seule fois dans le programme, par exemple au début.

    C'est en partie la cause de suites "trop souvent répétées".

  13. #13
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut
    Citation Envoyé par sjrd Voir le message
    Attention !

    Il ne faut surtout pas mettre Randomize dans la fonction de mélange. Il faut appeler cette procédure une et une seule fois dans le programme, par exemple au début.

    C'est en partie la cause de suites "trop souvent répétées".
    je n'ai pas trop compris ? pour la procédure de mélange, on a besoin de l'appeler plusieurs fois non ?

    en tout cas dans le programme j'ai besoin de mélanger qu'une seule fois, à l'exécution ...

    pour le code de anapurna je n'ai toujours pas réussis, je suis novice certes, mais je n'ai pas réussis à trouver TIntegerDynArray

    autre question pourquoi utilise un TStringGrid ? alors que le résultat, je le veut dans un array

    autres question bidon lol : vous pouvez me rappeler dans quel ongle le TStringGrid se trouve ? :p (je ne l'utilise pas, mais jlavais déjà croisé lol)

  14. #14
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut
    Citation Envoyé par Coussati Voir le message
    je n'ai pas trop compris ? pour la procédure de mélange, on a besoin de l'appeler plusieurs fois non ?
    Oui bien sûr. sjrd fait référence à l'appel de randomize et doit être effectué une et une seule fois.

    Dans la section initialization de ta fiche principale par exemple.

    @+ Claudius

  15. #15
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 874
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    le code d'anapurna fonctionne parfaitement (déclare type TIntegerDynArray=array of integer; )
    en adaptant à ton code et en conservant l'affichage après tri dans ListBox1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    type TMyArray=array[1..54] of Integer;
     
    procedure Shuffle(var Tableau: TMyArray);
    var
      i1, i2, iSwap:Integer;
    begin
      randomize;
      for i1:= High(Tableau) downto succ(low(Tableau)) do
      begin
        i2 := Random(i1)+ 1;
        iSwap := Tableau[i1];
        Tableau[i1] := Tableau[i2];
        Tableau[i2] := iSwap;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject) ;
    var
       a: TMyArray;
       i: Shortint;
    begin
       for i := Low(a) to High(a) do a[i] := i;
       Shuffle(a) ;
     
      ListBox1.Clear;
      for i := Low(a) to High(a)  
      do ListBox1.Items.Add(IntToStr(a[i])) ;
    end;
     
    // à la fin de l'unité :
     
    initialization
      Randomize; // sera appelé une seule fois (amorce le générateur pseudo-aléatoire)
     
    finalization
     
    end.

  16. #16
    Débutant
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 886
    Points : 330
    Points
    330
    Par défaut
    merci les gars ça l'air de fonctionner vous avez assuré ^^

    je met le tag résolu, et j'en profite pour faire une tite pub pour un autre prob un peu plus délicat

    http://www.developpez.net/forums/d66...el-tscrollbox/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. comportement /config shuffle(array)
    Par remond dans le forum Langage
    Réponses: 5
    Dernier message: 11/03/2011, 12h06
  2. Shuffle sur un array javacript
    Par SpaceFrog dans le forum Général JavaScript
    Réponses: 25
    Dernier message: 23/02/2010, 19h54
  3. Réponses: 5
    Dernier message: 04/12/2008, 13h45
  4. Bonjour Shuffle (mélanger un vecteur)
    Par Nodoso dans le forum Scheme
    Réponses: 9
    Dernier message: 06/12/2007, 22h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo