[Basic]Trier un tableau avec/sans doublons

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Avatar de l’utilisateur
alhazred
ManitOOu
ManitOOu
Messages : 3028
Inscription : 30 avr. 2011 23:08
Localisation : Casablanca (Maroc)

[Basic]Trier un tableau avec/sans doublons

Message par alhazred »

Bonjour à tous,

Sujet que je n'ai trouvé abordé qu'une fois par Dude (même pas sûr :oops: ; suis tombé dessus naguère, mais maintenant, pas moyen de le retrouver) ; j'ai voulu généraliser un peu, et en particulier traiter la conservation ou non des doublons.

On trouve également dans la bibliothèque Tools (module Strings) une fonction BubbleSortList, singulièrement lente (tri à bulle) pour de grands tableaux.

Ici, on utilise un tri fusion :
-- diviser le tableau en deux
-- trier chaque partie (récursivité)
-- imbriquer les deux parties triées : ajouter le plus petit des deux éléments suivants (un pour chaque partie).

Code : Tout sélectionner

'Tri rapide : séparer en deux, trier les parties, les imbriquer
'noDouble = true pour supprimer les doublons
'les indices commencent à 0
Function SortedList(list, noDouble As Boolean)
	Dim ub%
	ub = UBound(list)
	If ub<1 Then
		SortedList = list
		Exit Function
	End If
			
	Dim ub1%, list1, list2
	
	'Diviser la liste en deux
	ub1 = ub\2
	list1 = ListSegment(list,0,ub1)
	list2 = ListSegment(list,ub1+1,ub)
	
	'Trier les parties
	list1 = SortedList(list1,noDouble)
	list2 = SortedList(list2,noDouble)
	
	'Les imbriquer
	SortedList = SortedUnion(list1,list2,noDouble)
End Function

'************************************************************************
'Former une nouvelle liste en prenant à chaque fois le plus petit élément.
Function SortedUnion(list1, list2, noDouble As Boolean)
	Dim i1%, ub1%, elem1, i2%, ub2%, elem2, i%, ub%, elem
	ub1 = Ubound(list1)
	ub2 = UBound(list2)
	ub = ub1+ub2+1
	Dim list(0 To ub)
	
	'i1 = 0 : i2 = 0 : i = 0 'inutile
	While i1<=ub1 And i2<=ub2
		elem1 = list1(i1)
		elem2 = list2(i2)
		If noDouble And elem1=elem2 Then
			list(i) = elem1
			i1 = i1+1
			i2 = i2+1
		ElseIf elem2<elem1 Then '<--- ici pour changer le mode de tri
			list(i) = elem2
			i2 = i2+1
		Else
			list(i) = elem1
			i1 = i1+1
		End If
		i = i+1
	Wend
	
	'Une des listes est épuisée : compléter avec les éléments restants de l'autre liste
	If i2<=ub2 Then
		For i2=i2 To ub2
			list(i) = list2(i2)
			i = i+1
		Next i2
	Else
		For i1 =i1 To ub1
			list(i) = list1(i1)
			i = i+1
		Next i1
	End If
	
	'Redimensionner si des doublons ont été éliminés
	If i<=ub Then Redim Preserve list(0 To i-1)
	
	SortedUnion = list
End Function

'**********************************************************
'Retourne la liste des éléments pour les indices de lb à ub
'org (0 par défaut) est la base de la nouvelle liste
Function ListSegment(list, lb%, ub%, Optional org%)
	If IsMissing(org) Then org=0
	'décalage des indices
	Dim delta% : delta = lb-org
	
	Dim list1(org To ub-delta), i%
	For i = lb To ub
		list1(i-delta) = list(i)
	Next i
	ListSegment = list1
End Function
La version présentée ne trie que des tableaux de nombres ou de chaînes, en ordre croissant

Pour trier en ordre décroissant, il suffit de remplacer

Code : Tout sélectionner

ElseIf elem2<elem1 Then '<--- ici pour changer le mode de tri
par

Code : Tout sélectionner

ElseIf elem2>elem1 Then '<--- ici pour changer le mode de tri
Un exemple :
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Dernière modification par alhazred le 08 avr. 2014 10:47, modifié 4 fois.
À bientôt

LibO 4.1.5.3 et AOO 4.0.1 sous Windows 7, MRI et SDK pour les macros.

Et la sauvegarde incrémentée, c'est sympa !
SPPP
Membre OOrganisé
Membre OOrganisé
Messages : 94
Inscription : 14 août 2012 15:53

Re: [Basic]Trier un tableau avec/sans doublons

Message par SPPP »

Bonjour,

Je pense qu'il y a une erreur dans votre 2nd code, il y a 2 fois le signe "<".
alhazred a écrit :Bonjour à tous,
Pour trier en ordre décroissant, il suffit de remplacer

Code : Tout sélectionner

ElseIf elem2<elem1 Then '<--- ici pour changer le mode de tri
par

Code : Tout sélectionner

ElseIf elem2<elem1 Then '<--- ici pour changer le mode de tri
En tout cas, merci de m'avoir fait découvrir cette fonction ainsi que la bibliotheque "tools".

COOordialement,
SPPP.
Dernière modification par SPPP le 31 mai 2014 21:50, modifié 1 fois.
Lubuntu 14.04 - OOo 4.1.1
XP SP3 - OOo 4.1.0
XP SP3 - LOo 4.4.5.2
Avatar de l’utilisateur
Zelada
InconditiOOnnel
InconditiOOnnel
Messages : 930
Inscription : 27 févr. 2013 14:55

Re: [Basic]Trier un tableau avec/sans doublons

Message par Zelada »

Bonjour

et bien je pense que SPPP ne voit pas la différence entre

Code : Tout sélectionner

ElseIf elem2<elem1 Then 
et

Code : Tout sélectionner

ElseIf elem2<elem1 Then
:)

A+
LibreOffice 3.6.5.2 (version imposée) sous Windows XP SP3 au bureau
Avatar de l’utilisateur
alhazred
ManitOOu
ManitOOu
Messages : 3028
Inscription : 30 avr. 2011 23:08
Localisation : Casablanca (Maroc)

Re: [Basic]Trier un tableau avec/sans doublons

Message par alhazred »

Merci, SPPP et Zelada, il faut bien sûr remplacer < par > :oops: Erreur corrigée.

J'ai aussi ajouté un fichier-exemple.
À bientôt

LibO 4.1.5.3 et AOO 4.0.1 sous Windows 7, MRI et SDK pour les macros.

Et la sauvegarde incrémentée, c'est sympa !