Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text.RegularExpressions Class MaCase #Region "Propriétés de classe" ''' <summary> ''' Valeur en X mini de la grille ''' </summary> Public Shared Property Xmin As Integer = 1 ''' <summary> ''' Valeur en X maxi de la grille ''' </summary> Public Shared Property Xmax As Integer = 10 ''' <summary> ''' Valeur en Y mini de la grille ''' </summary> Public Shared Property Ymin As Integer = 1 ''' <summary> ''' Valeur en Y maxi de la grille ''' </summary> Public Shared Property Ymax As Integer = 7 #End Region #Region "Méthode de classe" ''' <summary> ''' Crée une instance de Case à partir d'un texte, si le texte n'est pas compatible, retourne null ''' </summary> ''' <param name="Coordonnees"></param> ''' <returns></returns> Public Shared Function NouvelleCase(Coordonnees As String) As MaCase Dim m As Match = Regex.Match(Coordonnees, "^(?<x>\d+);(?<y>\d+)$") If m.Success Then 'si le texte correspond au modèle 'on extrait x et y Dim x As Integer = Convert.ToInt32(m.Groups("x").Value) Dim y As Integer = Convert.ToInt32(m.Groups("y").Value) 'On vérifie qu'il sont compatibles de la grille If x >= Xmin AndAlso x <= Xmax AndAlso y >= Ymin AndAlso y <= Ymax Then Return New MaCase(x, y) 'on retourne une instance de Case, grâce au constructeur privé avec paramètres End If End If 'sinon, on retourne null Return Nothing End Function #End Region #Region "Constructeurs" ''' <summary> ''' Constructeur nécessaire pour la création d'une instance voisine ''' </summary> Private Sub New() End Sub ''' <summary> ''' Constructeur nécessaire pour la création d'une instance depuis un string au format "x;y" ''' </summary> ''' <param name="LeX"></param> ''' <param name="LeY"></param> Private Sub New(LeX As Integer, LeY As Integer) X = LeX Y = LeY 'crée la liste des voisins non null de la case en cours, 'cette fois on se sert du constructeur sans paramètres pour ne pas calculer indéfiniment des voisins VoisinsPotentiels = ({New MaCase With {.X = LeX, .Y = LeY + 1}, New MaCase With {.X = LeX, .Y = LeY - 1}, New MaCase With {.X = LeX + 1, .Y = LeY}, New MaCase With {.X = LeX - 1, .Y = LeY}}).Where(Function(c) c IsNot Nothing).ToList() End Sub #End Region #Region "Propriétés d'instance" ''' <summary> ''' Abscisse de la case ''' </summary> Public Property X As Integer ''' <summary> ''' Ordonnées de la case ''' </summary> Public Property Y As Integer ''' <summary> ''' Liste des voisins possibles de la case ''' </summary> Public Property VoisinsPotentiels As List(Of MaCase) #End Region Public Overrides Function ToString() As String Return String.Format("{0};{1}", X, Y) End Function #Region "Opérateurs" ''' <summary> ''' Opérateur d'égalité ''' </summary> ''' <param name="Un"></param> ''' <param name="Autre"></param> ''' <returns></returns> Public Shared Operator =(ByVal Un As MaCase, ByVal Autre As MaCase) As Boolean 'si Un ou Autre vaut null If Object.ReferenceEquals(Un, Nothing) Then Return Object.ReferenceEquals(Autre, Nothing) ElseIf Object.ReferenceEquals(Autre, Nothing) Then Return False End If 'Sinon on compare les coordonnées Return Un.X = Autre.X AndAlso Un.Y = Autre.Y End Operator ''' <summary> ''' Opérateur d'inégalité ''' </summary> ''' <param name="Un"></param> ''' <param name="Autre"></param> ''' <returns></returns> Public Shared Operator <>(ByVal Un As MaCase, ByVal Autre As MaCase) As Boolean Return Not (Un = Autre) End Operator #End Region End Class
Private Sub TestMatousso() 'initialisation d'un arrayList pour l'exemple Dim caseNoires As New ArrayList() caseNoires.Add("6;2") caseNoires.Add("4;3") caseNoires.Add("5;3") caseNoires.Add("6;3") caseNoires.Add("5;4") caseNoires.Add("4;5") caseNoires.Add("5;5") caseNoires.Add("8;7") caseNoires.Add("9;7") 'si finalement on décidait que la grille a une colonne de plus MaCase.Xmax = 11 Dim lesCasesNoires As New List(Of MaCase)() 'Création de la liste de travail For Each s As String In caseNoires 'on ne peut pas faire de Linq sur un ArrayList, alors on fait un foreach Dim c As MaCase = MaCase.NouvelleCase(s) If c IsNot Nothing Then lesCasesNoires.Add(c) End If Next s Dim lesGroupes As New List(Of List(Of MaCase))() Do While lesCasesNoires.Count > 0 'la recherche ci dessous va enlever les cases au fur et à mesure et s'arreter quand il n'y en aura plus 'Création d'un nouveau groupe qui commence avec la première case, que l'on enlève de la liste d'origine Dim laCase As MaCase = lesCasesNoires(0) lesCasesNoires.Remove(lesCasesNoires(0)) Dim g As New List(Of MaCase)() From {laCase} lesGroupes.Add(g) Do Dim voisinsPotentiels As List(Of MaCase) = g.SelectMany(Function(c) c.VoisinsPotentiels).ToList() 'collection de tous les voisins possibles des cases déjà dans le groupe Dim voisins As List(Of MaCase) = ( From p In voisinsPotentiels, c In lesCasesNoires Where p = c Select c).ToList() 'collection des cases se trouvant dans les voisins potentiels et les cases noires If voisins.Count = 0 Then Exit Do 'il n'y a plus de voisins on sort de la création de ce groupe End If 'On ajoute les voisins au groupe g.AddRange(voisins) 'on les enlève de la liste de cases noires For Each c As MaCase In voisins lesCasesNoires.Remove(c) Next c If lesCasesNoires.Count = 0 Then Exit Do 's'il n'y a plus de case à classer, pas la peine de faire une boucle de plus End If 'on recommence la même recherche à partir du groupe nouvellement constitué Loop Loop End Sub
Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CodeS SourceS
201 internautes nous ont dit merci ce mois-ci
Je voudrais, dans toutes ces coordonnées, isoler et partager en plusieurs groupes toutes celles correspondant à des cases qui se touchent.
une case ne contient rien, elle est juste caractérisée par sa coordonnée.
Je me retrouve donc avec un arraylist contenant une série de coordonnées correspondant aux cases noires,
Et j'utilise un arraylist tout simplement parce que je ne connais pas à l'avance le nombre de cases noires au départOk, mais une list(of ), est plus simple et souple à utiliser, et c’est aussi une liste chaînée
Je regarde quand j'ai un moment
Je trouve 15791 groupes au lieu de 16354, sur le fichier de test.
Je n'ai pas vérifié à grande échelle mais j'ai une idée pour le faire, mais je ne la mettrais pas en oeuvre ce soir.
Si de ton coté tu peux regarder ce que ça donne sur ton image.
Merci beaucoup pour toute cette aide et cette implication et bonne continuation !
matousso