unity desordenar array c# sorting shuffle

desordenar - C#: Buena/mejor implementación del método Swap



shuffle list c# unity (5)

Bueno, el código que ha publicado ( ref cards[n] ) solo puede funcionar con una matriz (no una lista), pero usaría simplemente (donde foo y bar son los dos valores):

static void Swap(ref int foo, ref int bar) { int tmp = foo; foo = bar; bar = tmp; }

O posiblemente (si quieres atómico):

Interlocked.Exchange(ref foo, ref bar);

Personalmente, no creo que me molestaría con un método de intercambio, solo hazlo directamente; esto significa que puede usar (ya sea para una lista o para una matriz):

int tmp = cards[n]; cards[n] = cards[i]; cards[i] = tmp;

Si realmente quisiera escribir un método de intercambio que funcionara en una lista o en una matriz, tendría que hacer algo como:

static void Swap(IList<int> list, int indexA, int indexB) { int tmp = list[indexA]; list[indexA] = list[indexB]; list[indexB] = tmp; }

(sería trivial hacer esto genérico); sin embargo, la versión original "en línea" (es decir, no un método) que trabaja en una matriz será más rápida.

Leí esta publicación sobre la baraja de cartas y en muchos algoritmos de mezcla y ordenación necesita intercambiar dos elementos en una lista o matriz. Pero, ¿cómo se ve un buen y eficiente método de intercambio?

Digamos para T[] y para List<T> . ¿Cómo implementaría mejor un método que intercambia dos elementos en esos dos?

Swap(ref cards[i], ref cards[n]); // How is Swap implemented?


Un buen intercambio es aquel en el que no intercambias los contenidos. En C / C ++ esto sería similar a intercambiar punteros en lugar de intercambiar los contenidos. Este estilo de intercambio es rápido y viene con alguna garantía de excepción. Desafortunadamente, mi C # está demasiado oxidado como para permitirme ponerlo en el código. Para tipos de datos simples, este estilo no le da mucho. Pero una vez que esté acostumbrado y tenga que lidiar con objetos más grandes (y más complicados), puede salvarle la vida.


Para cualquier persona que se pregunte, el intercambio también puede hacerse con los métodos de extensión (.NET 3.0 y posteriores).

En general, parece que no hay posibilidad de decir que los métodos de extensión "este" valor es ref, por lo que debe devolverlo y anular el valor anterior.

public static class GeneralExtensions { public static T SwapWith<T>(this T current, ref T other) { T tmpOther = other; other = current; return tmpOther; } }

Este método de extensión se puede usar así:

int val1 = 10; int val2 = 20; val1 = val1.SwapWith(ref val2);


¿Qué hay de esto? Es una implementación genérica de un método de intercambio. ¡Jit creará una versión compilada SOLAMENTE para los tipos cerrados, por lo que no tendrá que preocuparse por los perfomances!

/// <summary> /// Swap two elements /// Generic implementation by LMF /// </summary> public static void Swap<T>(ref T itemLeft, ref T itemRight) { T dummyItem = itemRight; itemLeft = itemRight; itemRight = dummyItem; }

HTH Lorenzo


Utilizar:

void swap(int &a, int &b) { // &a != &b // a == b OK a ^= b; b ^= a; a ^= b; return; }

No me di cuenta de que estaba en la sección C #. Este es el código C ++, pero debería tener la misma idea básica. Yo creo que ^ es XOR en C # también. Parece que en lugar de & puede necesitar "ref" (?). No estoy seguro.