2
votes

Comment mélanger un tableau multidimensionnel?

J'essaye de mélanger au hasard un tableau 2D. Comment puis-je le faire? Je ne connais que la façon de mélanger un tableau avec la méthode mélangée. Dois-je regrouper tous les tableaux 2D en un seul grand tableau et les mélanger et en faire un tableau 2D ou il existe une meilleure approche?

[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]


1 commentaires

Pourriez-vous également ajouter une sortie attendue? J'espère avoir bien répondu à votre question, mais je peux me tromper.


4 Réponses :


0
votes

Vous pouvez toujours le faire comme ceci:

[[3, 2, 1], [2, 7, 1], [9, 4, 1]]

L'une des sorties possibles étant celle-ci

var matrix = [[1, 3, 2], [7, 1, 2], [9, 4, 1]]
var shuffled = matrix.map({ $0.shuffled() })

print(shuffled)

Modifier:

Si la matrice entière doit être mélangée cependant, vous devriez probablement d'abord flatMap la matrice, mélanger le tableau, puis découper le tableau en une matrice.

Si vous êtes préoccupé par les performances, vous devriez alors utiliser un algorithme de mélange de tableaux bien connu ( Knuth shuffle ) , mais avec la matrice intacte. À la place, utilisez une variante de matrice linéarisée (où vous convertissez une position de matrice (x, y) en une position de vecteur (y * (x - 1)) + y)


1 commentaires

Mais cela ne mélangerait pas les valeurs de différentes lignes.



1
votes

Vous pouvez parcourir le tableau externe avec une boucle for et mélanger chaque tableau sur lequel vous itérez via la méthode shuffle. Voici mon idée en pseudocode:

new_array = []
for i=0; i < oldarray.length(); i++:
    new_array.append(oldarray[randomNumber])

Edit

Pour autant que je comprends votre question maintenant, j'essaierais d'ajouter le tableau existant à un nouveau tableau dans un non- ordre tellement aléatoire, comme ceci:

for inner_array in outer_array:
    shuffle(inner_array)

Il faudrait rechercher d'éventuels doublons (c'est-à-dire en supprimant le tableau de la boucle for de l'ancien tableau) et de cause que votre randomNumber est généré entre les bordures de l'ancien tableau.

Vous pouvez utiliser la première et la deuxième réponse ensemble en fonction de vos besoins.


2 commentaires

Le problème est, comme l'a dit Martin R, que cela ne ferait que mélanger chaque ligne d'une matrice.


Okay semble que je me suis trompé de question. Vous souhaitez mélanger le tableau externe? Ou le tableau intérieur et extérieur?



1
votes

Tout d'abord, obtenez un seul tableau mélangé combiné à partir du tableau multidimensionnel, c'est-à-dire

let result = shuffled.chunks(of: 3) [[3, 1, 2], [5, 6, 4], [7, 8, 9], [11, 10, 12]]

Créez une extension qui divise un seul tableau en morceaux, c'est-à-dire

extension Array {
    func chunks(of size: Int) -> [[Element]] {
        return stride(from: 0, to: self.count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}


2 commentaires

arr.flatMap ({$ 0.shuffled ()}) mélangerait chaque ligne séparément, puis concaténerait les résultats. Il ne mélange pas les valeurs de différentes lignes.


@MartinR Ouais. Cela aussi. Merci pour la mise à jour. Je pense que c'est plus pertinent.



2
votes

Vous avez raison de dire qu'une bonne façon d'aborder la lecture aléatoire d'un tableau 2D est de l'aplatir et de mélanger les valeurs. La partie délicate est de savoir comment ramener les valeurs mélangées dans la structure originale du tableau.

En transformant le tableau mélangé en un itérateur iter , nous pouvons appeler iter.next () pour obtenir chaque valeur et utiliser des cartes imbriquées pour accéder et remplacer les valeurs d'origine:

[[0, 1, 0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 1, 1, 1, 2, 0, 1], [0, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 0, 1, 0, 2, 1, 2, 1, 0, 1], [1, 0, 0, 0, 2, 1, 1, 0, 1, 1], [1, 1, 0, 0, 0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 2, 0, 0, 1, 1, 0], [1, 0, 1, 1, 0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 0, 1, 1, 1, 0], [1, 1, 0, 0, 0, 0, 1, 0, 0, 0]]
let array = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
             [2, 2, 2, 2, 2, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

let shuffled = shuffle2D(array)
print(shuffled)

En faire une fonction générique: func shuffle2D (_ arr: [[T]]) -> [[T]]

Nous pouvons transformer cela en une fonction générique qui peut mélanger n'importe quel tableau 2D:

[["e", "a"], ["b", "d"], ["f", "c"]]

Remarque: I ont changé la map interne en compactMap afin d'éviter de forcer le déroulement de iter.next().

Exemples:

print(shuffle2D([["a", "b"], ["c", "d"], ["e", "f"]]))
[[2, 5, 6], [3, 1, 4]]
print(shuffle2D([[1, 2, 3], [4, 5, 6]]))
func shuffle2D<T>(_ arr: [[T]]) -> [[T]] {
    var iter = arr.joined().shuffled().makeIterator()

    return arr.map { $0.compactMap { _ in iter.next() }}
}
[[4], [5, 1], [3, 6, 2]]
var arr = [[1], [2, 3], [4, 5, 6]]

var iter = arr.joined().shuffled().makeIterator()

let arr2 = arr.map { $0.map { _ in iter.next()! } }

print(arr2)


0 commentaires