Algo tri tableau [Résolu]

Signaler
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
-
Messages postés
13280
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
-
 Bonsoir à tous,

Question quasi similaire à un récent post (Tableau Excel de tyju).

Avec le tableau ci-dessous (Participants), j'obtiens un résultat par tri Poids/Joueur.
5,90    Joueur1
5,88    Joueur15
5,86    Joueur12
5,86    Joueur8
5,85    Joueur4
5,82    Joueur2
5,8     Joueur3
5,6     Joueur7

Comment puis-je obtenir un tableau,  trié sur les réponses les plus proches de PoidsReel (ici 5.87) ???

Resultat souhaité:
5,88    Joueur15 (1 ex aequo)
5,86    Joueur12 (1 ex aequo)
5,86    Joueur8  (1 ex aequo)
5,85    Joueur4 (4ème)
5,90    Joueur1 (5ème)
5,82    Joueur2 (6ème)
5,8     Joueur3 (7ème)
5,6     Joueur7 (8ème)

PCPT parlait de la fonction abs():
Function IsNear(ByVal dValueToHave , ByVal dValueToCompare , ByVal iNear)
    IsNear = (Abs(dValueToHave - dValueToCompare) <= Abs(iNear))
End Function

Je n'ai pas saisi !!!
D'autre part, j'ai peut-être même un tableau de trop dans ce début de script.

Dim Participants
Participants = array(array("Joueur3",5.8),array("Joueur15",5.88), _
               array("Joueur4",5.85), array("Joueur1",5.90), _
               array("Joueur12",5.86),array("Joueur7",5.6), _
               array("Joueur8",5.86),array("Joueur2",5.82))
              
MsgBox PourQuiLesSaucissons(Participants, 5.87)

Function PourQuiLesSaucissons(Participants, PoidsReel)
Dim i, imax, z, r, Valeur, Cible, liste
imax = 0
For i = 0 To UBound(Participants)
    imax = imax + 1
    ReDim Preserve Tableau(2, imax)
    Tableau(1, imax) = Participants(i)(0)
    Tableau(2, imax) = Participants(i)(1)
Next

Do
   Valeur = 0
   For i = 1 To imax - 1
       If Tableau(2, i) < Tableau(2, i + 1) Then
          For z = 1 To 2
              Cible = Tableau(z, i)
              Tableau(z, i) = Tableau(z, i + 1)
              Tableau(z, i + 1) = Cible
          Next
          Valeur = 1
       End If
  Next
Loop While Valeur = 1
'Enumération tableau trié
For r = 1 To imax
    liste = liste & vbCrLf & r & vbtab & _
            Tableau(2, r) & vbtab & Tableau(1, r)
Next
liste = vbCrLf & "Ordre      Pesée       Equipe" & vbCrLf & liste

PourQuiLesSaucissons = liste
End Function

Merci à ceux/celles qui voudront bien me rappeler les bases des maths !

jean-marc

3 réponses

Messages postés
13280
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
41
salut,

je disais pour abs ce que tu vas voir ci-dessous ^^

j'ai essayé de faire en VBS mais j'ai une erreur de parenthèse, çà doit venir de la déclaration des tableaux je suppose
en VB6 (mal typé de par le fait) çà donne çà :

Option Explicit

Private Sub Form_Load()
    Dim Participants
    Participants = Array(Array("Joueur3", 5.8), Array("Joueur15", 5.88), _
                   Array("Joueur4", 5.85), Array("Joueur1", 5.9), _
                   Array("Joueur12", 5.86), Array("Joueur7", 5.6), _
                   Array("Joueur8", 5.86), Array("Joueur2", 5.82))
                  
                  
    Dim Apres 'tableau retour
    Apres = PourQuiLesSaucissons(Participants, 5.87)
    
    Dim s 'chaine msgbox
    Dim i

'   tableau de
départ
    s = "JOUEUR" & vbTab & "PESEE" & vbCrLf & "=================" & vbCrLf
    For i = 0 To 7
        s = s & Participants(i)(0) & vbTab &
Participants(i)(1) &
vbCrLf
    Next i

'   tableau
d'arrivée
    s = s & vbCrLf & vbCrLf & "JOUEUR" & vbTab & "PESEE" & vbTab & "DIFF" & vbTab & "POS" & vbTab & "EXAEQUO" & vbCrLf & "=================" & vbCrLf
    For i = 0 To 7
        s = s & Apres(i, 0) & vbTab & Apres(i, 1) & vbTab & Apres(i,
2) & vbTab &
Apres(i, 3) & vbTab
& Apres(i, 4) &
vbCrLf
    Next i

    MsgBox s
    
    
    
Unload Me
End Sub

Function PourQuiLesSaucissons(Participants, PoidsReel)
    Dim i, j 'boucle
    
'   un tableau dans
l'ordre, à 5 dimensions : nom / valeur / valeur de différence /
position de résultat / ex aequo
    Dim aNotSorted(0 To 7, 0 To 4)
    
    For i = 0 To 7
        aNotSorted(i, 0) = Participants(i)(0)
        aNotSorted(i, 1) = Participants(i)(1)
        aNotSorted(i, 2) = Abs(CCur(Round(aNotSorted(i, 1) - PoidsReel, 2))) 'utile
pour calculer et trier
        'Debug.Print
aNotSorted(i, 2)
    Next i

'   on tri selon la proximité
du poid, donc du plus petit au plus grand
    Dim aTmp(0, 2)
    
    For i = 0 To 6
        For j = i + 1 To 7
            If aNotSorted(i, 2) > aNotSorted(j, 2) Then
                aTmp(0, 0) = aNotSorted(j, 0): aTmp(0,
1) = aNotSorted(j,
1): aTmp(0, 2) = aNotSorted(j, 2)
                aNotSorted(j, 0) = aNotSorted(i, 0): aNotSorted(j, 1) = aNotSorted(i, 1): aNotSorted(j, 2) = aNotSorted(i, 2)
                aNotSorted(i, 0) = aTmp(0,
0): aNotSorted(i,
1) aTmp(0, 1): aNotSorted(i, 2) aTmp(0, 2)
            End If
        Next j
    Next i

'   on met la
position
    aNotSorted(0, 3) = 1
    For i = 1 To 7
        If aNotSorted(i, 2) = aNotSorted(i - 1, 2) Then
            aNotSorted(i, 3) = aNotSorted(i - 1, 3)
            aNotSorted(i, 4) = True
            aNotSorted(i - 1, 4) = True
        Else
            aNotSorted(i, 3) = i + 1
            aNotSorted(i, 4) = False
        End If
    Next i
    
    PourQuiLesSaucissons = aNotSorted
End Function

donc tu vois ce que je disais pour la différence....
une fois le topX trouvé, on sait qu'on est à autant près...

donc on récupère cette différence mais forcément positive, pour trier

5.4 et 5.6 sont bel et bien autant éloigné l'un que l'autre de 5.5
5.5-5.4 0.1         abs> 0.15.5-5.6 -0.1       abs> 0.1

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Messages postés
13280
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
41
re,

7 par ubound, vi évidemment, je ne me suis pas trop foulé (et ne maitrisant pas VBS...)
redim au lieu de dim (VBS), voilà bien une chose à laquelle je n'aurais pas pensé ;)

conversion currency (à savoir que je ne savais pas si çà aurait été accepté en VBS), on est forcé puisque le double est trop précis...
sinon un joli N,.......E+... ; alors apparemment considéré comme string (variant vers string, tant VBS que VB6 puisqu'on part variant/tableau non typé)
vartype (en VB6 en tout cas) nous ôterait du doute mais c'est certain, on doit passer par le ccur
 aNotSorted(0, 3) 1> pas utile de commencer la boucle à 0 puisqu'à 1 elle se charge de mettre le "exaequo" du précédent (donc 0) et comme tout est déjà trié, on met juste la première valeur.
comme ces valeurs sont déjà triées, l'indice 0 est forcément le premier (exeaquo ou non)
donc RETOUR(1er_gagnant, position) = 1er

bonne soirée ;)
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
26
Bonsoir PCPT,
Je me doutais bien d'une réponse de ta part.

En remplacant 7 par UBound(Participants) et  ReDim aNotSorted(imax, 4) à la place du Dim,
la fonction devient paramétrable.

Brillant ... très brillant l'algo de aNotSorted.

Vu aussi la conversion du double en variante de sous-type Currency pour l'abs().

Je n'est pas compris le aNotSorted(0, 3) = 1


Merci PCPT.


@+.

jean-marc