Page 1 sur 1

[Résolu] Tri croissant decroissant sur 2 colonnes d'un table

Publié : dim. 19/avr./2009 11:35
par Ganagyre
Bonjour.

Avec la procedure suivante, un tri croissant ou décroissant s'opére sur un des elements (colonne) d'un tableau, contenant des valeurs numeriques.

Code : Tout sélectionner


Procedure Trie(offset,Sens)

  NewList TriTab.Tab()
  For nn=1 To Numeros
    AddElement(TriTab())
    TriTab()\ElementN1 = Tableau(1,nn)
    TriTab()\ElementN2 = Tableau(2,nn)
    TriTab()\ElementN3 = Tableau(3,nn)
  Next

  SortStructuredList(TriTab(), Sens, offset, #PB_Sort_Long)
  nn=1
  ForEach TriTab()
    Tableau(1,nn) =  TriTab()\ElementN1
    Tableau(2,nn) =  TriTab()\ElementN2
    Tableau(3,nn) =  TriTab()\ElementN3
    nn+1
  Next

EndProcedure

;Tri sur le 3 élement/Ordre decroissant

Trie(OffsetOf(Tab\ElementN3),1)


Comment ajouter une option de tri sur un autre element, style

Tri décroissant sur la "colonne 3 " en gardant un ordre croissant des valeurs sur la " colonne 1.

10;10;25
35;10;25
99;10;25
01;10;35
09;10;35
...

Un peu comme les option Tri ou filtre possible sur Excel.

Merci à tous .

Publié : dim. 19/avr./2009 11:59
par comtois
en lançant deux tris successivement ? ça ne marche qu'avec le tri des listes chainées. Voir la réponse de Freak dans ce post

http://www.purebasic.fr/english/viewtopic.php?t=35857
Since PB 4.30, SortStructuredList (and SortList) use Mergesort which is a stable sort, so if you first sort all the list by titles and then again by album you will get a list which is sorted by album and each album is sorted by title.

Note that this does not work with Arrays, as SortArray uses Quicksort which is unstable. (ie the sorting of the secondary key would be lost)
Je ne l'ai jamais testé, tu nous diras ce que ça donne :)

Publié : mar. 28/avr./2009 14:44
par Ganagyre
Merci comtois pour ce lien interressant.

Entre temps, en parcourant le forum, j'ai pu y trouver de bonnes idées .
(j'etudie encore certains codes)

Pour obtenir un TRI Croissant Colonne 1 et Decroissant colonne 2, une 3 ieme colonne avec une petite formule .
Ensuite TRI Decroissant sur la colonne 3 donne le bon ordre pour la 1 et 2.

Hum,sauf que maintenant , je "bug" sur la sauvegarde du fichier qui reste vide !

Code : Tout sélectionner

;<<<<<<<<<<<<__VARIABLES__>>>>>>>>>>>>>>>>>>>>>>>
tri.b = 1   ; Tri / 0=Croissant / 1=Decroissant    
JEUX.l = 100 
a.l
b.l = 50
n.l
z.l :j.l
Structure Match
    Equipe.l
    Points.l
    Classement.d
EndStructure

Dim FOOT.Match(JEUX)

Global Dim Tableau.l(3,JEUX) ;(colonnes,Lignes)
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;========== Boucle Remplissage données
For a = 1 To JEUX
    ;----------------EQUIPE / Par Ordre Croissant
    FOOT(a)\Equipe=a
    ;----------------POINTS 
    FOOT(a)\Points=Random(b)+1 
    ;----------------CLASSEMMENT / Sans Doublons   
    FOOT(a)\Classement=FOOT(a)\Points-FOOT(a)\Equipe/100000000000
Next 
;========== Fin Boucle 

Procedure Sauve(File.s) 
  CreateFile(1,File) 
    For n=1 To JEUX 
      WriteStringN(1,Str(Tableau(1,n))+";"+Str(Tableau(2,n))+";"+Str(Tableau(3,n)))
      ;
    Next 
  CloseFile(1) 
EndProcedure  

;------------ Triage Decroissant Du Classement -----      
SortStructuredArray (FOOT(),Tri, OffsetOf (Match\Classement), #PB_Sort_Double )
;---------------------------------------------------     
;
;------------ Remplissage Tableau ------------------      
 For z = 1 To JEUX 
    Tableau(1,z) =  FOOT(z)\Equipe
    Tableau(2,z) =  FOOT(z)\Points 
    Tableau(3,z) =  FOOT(z)\Classement  
 Next 
 ;----------- Fin Remplissage Tableau     
 
;========== Sauvegarde TABLEAU      
Sauve("d:\A_Structure Sauve 1000.txt")
;========== 
;____________Verification Si Triage Fonctionne ____     
OpenConsole () 

 For j =0 To JEUX
    PrintN ( "Equipe =  " + Str (FOOT(j)\Equipe)+ " Points = " + Str (FOOT(j)\Points)+ " Classement = " + Str (FOOT(j)\Classement))
 Next 
 
Input ()
CloseConsole ()


Publié : mar. 28/avr./2009 15:00
par djes
Tu as oublié de rendre globale ta variable Jeux, ou de la partager dans ta procedure sauve() avec Shared.

Publié : mar. 28/avr./2009 15:01
par zaphod
Faut peut être mettre la variable jeux en global ?

Publié : mar. 28/avr./2009 18:04
par Le Soldat Inconnu
j'ai cette méthode de tri qui traine aussi
elle peut permettre de mixer les types de données à trier (string et long par exemple), a vous d'adapter le code

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4
; 
; Explication du programme :
; Tri d'une liste chainée composé d'une structure d'abord sur l'élément a de la liste puis sur l'élément c

; On crée une liste chainé avec des valeurs aléatoires
Structure Tableau_Info
  a.l
  b.l
  c.l
EndStructure
NewList Tableau.Tableau_Info()

For n = 1 To 20
  AddElement(Tableau())
  Tableau()\a = Random(10)
  Tableau()\b = Random(20)
  Tableau()\c = Random(30)
Next

;- Procédé

; On tri d'abord sur "a"
SortStructuredList(Tableau(), 0, OffsetOf(Tableau_Info\a), #PB_Sort_Long)

  ; Puis sur "c"
Tri = -1 ; Mettre ici une valeur qui n'existe pas
Compteur = 0
Depart = -1
ForEach Tableau()
  If Tri = Tableau()\a ; On compte le nombre d'élément à la suite qui ont "a" égaux
    If Depart < 0
      Depart = ListIndex(Tableau()) - 1
    EndIf
    Compteur + 1
  Else ; Puis on trie cette liste d'élément sur "c"
    If Compteur
      SortStructuredList(Tableau(), 0, OffsetOf(Tableau_Info\c), #PB_Sort_Long, Depart, Depart + Compteur)
      SelectElement(Tableau(), Depart + Compteur + 1)
    EndIf
    Compteur = 0
    Depart = -1
    Tri = Tableau()\a ; On copie la nouvelle valeur pour trouvé la prochaine suite d'élément avec "a" égaux
  EndIf
Next
If Compteur ; Si on finis la liste chainée avec une série d'élément "a" égaux
  SortStructuredList(Tableau(), 0, OffsetOf(Tableau_Info\c), #PB_Sort_Long, Depart, Depart + Compteur)
EndIf

; On affiche le résultat
ForEach Tableau()
  Debug Str(Tableau()\a) + " ; " + Str(Tableau()\b) + " ; " + Str(Tableau()\c)
Next


;- Test de rapidité

ClearList(Tableau())
For n = 1 To 50000
  AddElement(Tableau())
  Tableau()\a = Random(10)
  Tableau()\b = Random(20)
  Tableau()\c = Random(50)
Next

Temps1 = ElapsedMilliseconds()

; On tri d'abord sur "a"
SortStructuredList(Tableau(), 0, OffsetOf(Tableau_Info\a), #PB_Sort_Long)

  ; Puis sur "c"
Tri = -1 ; Mettre ici une valeur qui n'existe pas
Compteur = 0
Depart = -1
ForEach Tableau()
  If Tri = Tableau()\a ; On compte le nombre d'élément à la suite qui ont "a" égaux
    If Depart < 0
      Depart = ListIndex(Tableau()) - 1
    EndIf
    Compteur + 1
  Else ; Puis on trie cette liste d'élément sur "c"
    If Compteur
      SortStructuredList(Tableau(), 0, OffsetOf(Tableau_Info\c), #PB_Sort_Long, Depart, Depart + Compteur)
      SelectElement(Tableau(), Depart + Compteur + 1)
    EndIf
    Compteur = 0
    Depart = -1
    Tri = Tableau()\a ; On copie la nouvelle valeur pour trouvé la prochaine suite d'élément avec "a" égaux
  EndIf
Next
If Compteur ; Si on finis la liste chainée avec une série d'élément "a" égaux
  SortStructuredList(Tableau(), 0, OffsetOf(Tableau_Info\c), #PB_Sort_Long, Depart, Depart + Compteur)
EndIf

Temps2 = ElapsedMilliseconds()

; On affiche le résultat
MessageRequester("Tri", Str(Temps2 - Temps1) + "ms")
une autre méthode un peu plus bête pour trier sur plusieurs éléments d'un tableau.
Elle peut-être un peu moins rapide mais elle fonctionne avec tout les types de variables et elle est facile à faire

l'astuce consiste à ajouter un champ "Tri" dans la structure du tableau

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4
; 
; Explication du programme :
; Trier un tableau avec structure sur plusieurs critères

Structure Valeur
  a.s
  b.l
  c.f
  Tri.s
EndStructure

Global NewList Tableau.Valeur()

; Remplissage aléatoire
For n = 1 To 20
  AddElement(Tableau())
  Tableau()\a = Chr(Random(25) + 65)
  Tableau()\b = Random(9)
  Tableau()\c = Random(20) / 10
Next

; On veut trier d'abord sur "c" puis sur "a et enfin sur "b"
ForEach Tableau()
  Tableau()\Tri = StrF(Tableau()\c) + Tableau()\a + Str(Tableau()\b)
Next

; on trie
SortStructuredList(Tableau(), #PB_Sort_Ascending, OffsetOf(Valeur\Tri), #PB_Sort_String)

; on affiche
ForEach Tableau()
  Debug Tableau()\a + " , " + Str(Tableau()\b) + " , " + StrF(Tableau()\c)
Next

Publié : mer. 29/avr./2009 12:16
par Ganagyre
Merci à vous, djes, zaphod , Le Soldat Inconnu.

L'affectation Global qui manquait en effet à une variable !
(punaise ce que j'ai pu chercher ou était le truc qui clochait) .

Le Soldat Inconnu, trés instructif les 2 méthodes de tri, il y a de quoi adapter selon les besoins en effet.


:D