Re: Coment trier un tableau structuré sur deux champs...
Publié : dim. 06/sept./2015 22:29
zen Falsam , brayane(dayvid) à fait des efforts, ne casse pas tout et revenons à l'essentiel.
Forums PureBasic - Français
https://www.purebasic.fr/french/
Code : Tout sélectionner
Structure TESTi
Champs1.i
Champs2.i
EndStructure
Structure TESTx
StructureUnion
champs3.TESTi
champs4.q
EndStructureUnion
EndStructure
MAXT=200
Dim Tableau.Testx(MAXT)
For I = 0 To MAXT
; *** premier essai tous les champs sont positifs ****
Tableau(I)\champs3\Champs2 = Random(9, 0)
;**** deuxième essai le champ de poids fort peut être négatif *****
; Tableau(I)\champs3\Champs2 = Random(9, 0)*Pow(-1,Random(1,0)) ; permet de générer des nombres négatifs
Tableau(I)\champs3\Champs1= Random(1000, 100)
;**** Troisième essai le champ de poids faible peut être négatif
; Tableau(I)\champs3\Champs1= Random(1000, 100)*Pow(-1,Random(1,0)); permet de générer des nombres négatifs (valable en valeur absolue)
Next
SortStructuredArray(Tableau(), #PB_Sort_Ascending, OffsetOf(TESTx\champs4), #PB_Quad )
For I = 0 To MAXT
Debug Str(Tableau(I)\champs3\Champs2) + " - " + Str(Tableau(I)\champs3\Champs1) ;+ " - " + Str(tableau(i)\champs4) ; Commentaire à retirer si vous désirez voir la valeur du champ4 en xx.q
Next
Excellent aussi.Spock a écrit :excellent, et mon code ? il marche mon code ? ou bien ?
Code : Tout sélectionner
Structure TEST
Cle.s
Champs1.i
Champs2.i
EndStructure
MAXT=200
Dim Tableau.Test(MAXT)
For I = 0 To MAXT
Tableau(I)\Champs1 = Random(9, 0)*Pow(-1,Random(1,0)) ; permet de générer des nombres négatifs
Tableau(I)\Champs2 = Random(1000, 100);*Pow(-1,Random(1,0)) ; permet de générer des nombres négatifs
With Tableau(i)
\Cle = Str(\Champs1) + RSet(Str(\Champs2), 6, "0")
EndWith
Next
SortStructuredArray(Tableau(), #PB_Sort_Ascending, OffsetOf(TEST\Cle), #PB_String)
For I = 0 To MAXT
Debug Str(Tableau(I)\Champs1) + " - " + Str(Tableau(I)\Champs2)
Next
PAPIPP a écrit :Revenons à l’algo de falsam Denis et LSI et essayons cet algo avec des nombres négatifs
La demande initiale de Brayane (sans faute) ne portant pas sur les nombres négatifs, j'ai effectivement procédé à un tri alpha et forcément ..... ça ne fonctionne pas avec les nombres négatifs.PAPIPP a écrit :Cet algo n’est pas correct pour aucun des deux champs négatifs.
Code : Tout sélectionner
Declare RandomSign()
Structure Test
Cle.i
Champs1.i
Champs2.i
EndStructure
Dim Tableau.Test(99)
For I = 0 To 99
Tableau(I)\Champs1 = Random(9, 0) * RandomSign()
Tableau(I)\Champs2 = Random(1000, 100)
With Tableau(i)
\Cle = \Champs1 * 9 * 1000 + \Champs2
EndWith
Next
SortStructuredArray(Tableau(), #PB_Sort_Ascending, OffsetOf(Test\Cle), #PB_Integer)
For I = 0 To 99
Debug RSet(Str(Tableau(I)\Champs1), 3, " ") + "=> " + RSet(Str(Tableau(I)\Champs2), 4, "0")
Next
Procedure RandomSign()
ProcedureReturn Random(1)*2-1
EndProcedure
Je vote pour, c'est vraie que se serais vraiment cool d'avoir çaDenis a écrit :Merci PAPIPP pour toutes ces précisions.
"L'algo" de LSI je l'utilise dans mon projet pour trier des icônes (dimension, profondeur etc.), je n'ai jamais à traiter de nombre négatifs, alors pour l'instant je garde.
C'est vrai que Fred (ou Freak) devrait peut-être améliorer les choses, voire proposer plusieurs types de tri avec une constante :
#PB_Sort_bulles, #PB_Sort_insertion , #PB_Sort_fusion ou d'autres, c'est juste pour soumettre l'idée.
Code : Tout sélectionner
Declare RandomSign()
Structure TEST
Cle.q
Champs1.i
Champs2.i
EndStructure
maxt=200
Dim Tableau.Test(MAXT)
For I = 0 To MAXT
Tableau(I)\Champs1 = Random(9, 0) * RandomSign()
Tableau(I)\Champs2 = Random(1000, 100)* RandomSign()
With Tableau(i)
\Cle = \Champs1 * $7FFFFFFF*2+$7FFFFFFF + \Champs2
EndWith
Next
SortStructuredArray(Tableau(), #PB_Sort_Ascending, OffsetOf(TEST\Cle), #PB_Quad)
For I = 0 To MAXT
Debug RSet(Str(Tableau(I)\Champs1), 3, " ") + "=> " + RSet(Str(Tableau(I)\Champs2), 4, "0")+ " clé= " +Str(tableau(I)\Cle)
Next
Procedure RandomSign()
ProcedureReturn Random(1)*2-1
EndProcedure
Code : Tout sélectionner
Structure TEST
Nom.s
Champs1.i
Champs2.d
EndStructure
Global maxt=200
Procedure TRIBULLE(Array TAB.test(1),Offset,Type,ascdesc)
Protected i,itemCount,hasChanged
itemCount=ArraySize(TAB())
LongTerm=TAB(1)-TAB(0)
*mem=AllocateMemory(Longterm, #PB_Memory_NoClear)
Macro inverseterm
CopyMemory(TAB(i), *Mem, LongTerm)
CopyMemory(TAB(i+1), TAB(i), LongTerm)
CopyMemory(*Mem, TAB(i+1), LongTerm)
hasChanged = #True
EndMacro
itemCount=ArraySize(TAB())
LongTerm=TAB(1)-TAB(0)
Repeat
hasChanged = #False
itemCount - 1
For i = 0 To itemCount
Select ascdesc
;******************************** cas du tri ascendant ******************************
Case #PB_Sort_Ascending
Select Type
Case #PB_Byte ; Le champ de la Structure est un octet (.b)
If PeekB(tab(i)+offset)>PeekB(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Word ; Le champ de la Structure est un word (.w)
If PeekW(tab(i)+offset)>PeekW(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Long ; Le champ de la Structure est un long (.l)
If PeekL(tab(i)+offset)>PeekL(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_String ; Le champ de la Structure est un string (.s ou $)
; Les strings fixe (fixed strings) ne sont pas supportées)
; Resultat$ = PeekS(*Memoire [, Longueur [, Format]])
; Format
; #PB_Ascii : Format ASCII.
; #PB_UTF8 : Format UTF-8.
; #PB_Unicode: Format Unicode.
; Par défaut ascii
If PeekS(PeekL(tab(i)+offset))>PeekS(PeekL(tab(i+1)+offset))
inverseterm
EndIf
Case #PB_Float ; Le champ de la Structure est un flottant (.f)
If PeekF(tab(i)+offset)>PeekF(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Double ; Le champ de la Structure est un double (.d)
If PeekD(tab(i)+offset)>PeekD(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Quad ; Le champ de la Structure est un quad (.q)
If PeekQ(tab(i)+offset)>PeekQ(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Character:; Le champ de la Structure est un caractère (.c)
If PeekC(tab(i)+offset)>PeekC(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Integer ; Le champ de la Structure est un integer (.i)
If PeekI(tab(i)+offset)>PeekI(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Ascii ; Le champ de la Structure est un caractère ascii (.a)
If PeekA(tab(i)+offset)>PeekA(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Unicode ; Le champ de la Structure est un caractère unicode (.u)
If PeekU(tab(i)+offset)>PeekU(TAB(i + 1)+offset)
inverseterm
EndIf
EndSelect
;******************************** cas du tri descendant ******************************
Case #PB_Sort_Descending
Select Type
Case #PB_Byte ; Le champ de la Structure est un octet (.b)
If PeekB(tab(i)+offset)<PeekB(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Word ; Le champ de la Structure est un word (.w)
If PeekW(tab(i)+offset)<PeekW(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Long ; Le champ de la Structure est un long (.l)
If PeekL(tab(i)+offset)<PeekL(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_String ; Le champ de la Structure est un string (.s ou $)
; Les strings fixe (fixed strings) ne sont pas supportées)
; Resultat$ = PeekS(*Memoire [, Longueur [, Format]])
; Format
; #PB_Ascii : Format ASCII.
; #PB_UTF8 : Format UTF-8.
; #PB_Unicode: Format Unicode.
; Par défaut ascii
If PeekS(PeekL(tab(i)+offset))<PeekS(PeekL(tab(i+1)+offset))
inverseterm
EndIf
Case #PB_Float ; Le champ de la Structure est un flottant (.f)
If PeekF(tab(i)+offset)<PeekF(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Double ; Le champ de la Structure est un double (.d)
If PeekD(tab(i)+offset)<PeekD(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Quad ; Le champ de la Structure est un quad (.q)
If PeekQ(tab(i)+offset)<PeekQ(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Character:; Le champ de la Structure est un caractère (.c)
If PeekC(tab(i)+offset)<PeekC(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Integer ; Le champ de la Structure est un integer (.i)
If PeekI(tab(i)+offset)<PeekI(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Ascii ; Le champ de la Structure est un caractère ascii (.a)
If PeekA(tab(i)+offset)<PeekA(TAB(i + 1)+offset)
inverseterm
EndIf
Case #PB_Unicode ; Le champ de la Structure est un caractère unicode (.u)
If PeekU(tab(i)+offset)<PeekU(TAB(i + 1)+offset)
inverseterm
EndIf
EndSelect
EndSelect
Next
Until hasChanged = #False
EndProcedure
Procedure RandomSign()
ProcedureReturn Random(1)*2-1
EndProcedure
Dim Tableau.Test(MAXT)
For I = 0 To MAXT
Tableau(I)\Champs1 = Random(9, 0) * RandomSign()
Tableau(I)\Champs2 = Random(1000, 100)* RandomSign()
tableau(i)\Nom="Dupond Pierre Jean Simon"+Str(Random(MAXt,0))
Next
; For I = 0 To MAXT
; Debug RSet(Str(Tableau(I)\Champs1), 3, " ") + "=> " + RSet(Str(Tableau(I)\Champs2), 4, "0")+ " "+tableau(I)\Nom
; Next
Debug "******************** Apès Tri"
TRIBULLE(tableau(),OffsetOf(test\Champs2),TypeOf(test\Champs2),#PB_Sort_Ascending)
TRIBULLE(tableau(),OffsetOf(test\Champs1),TypeOf(test\Champs1),#PB_Sort_Descending)
; TRIBULLE(tableau(),OffsetOf(test\Nom),TypeOf(test\Nom),#PB_Sort_Ascending)
; TRIBULLE(tableau(),OffsetOf(test\Nom),TypeOf(test\Nom),#PB_Sort_Descending)
;
For I = 0 To MAXT
Debug RSet(Str(Tableau(I)\Champs1), 3, " ") + "=> " + RSet(Str(Tableau(I)\Champs2), 4, "0") + " "+tableau(I)\Nom
Next