Buscar..


Introducción

En mi camino hacia el estudio de la programación ha habido problemas simples, pero interesantes para resolver como ejercicios. Uno de esos problemas era rotar una matriz (u otra colección) por un cierto valor. Aquí compartiré contigo una fórmula simple para hacerlo.

Ejemplo de un método genérico que rota una matriz en un turno dado

Me gustaría señalar que giramos a la izquierda cuando el valor de cambio es negativo y giramos a la derecha cuando el valor es positivo.

    public static void Main()
    {
        int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int shiftCount = 1;
        Rotate(ref array, shiftCount);
        Console.WriteLine(string.Join(", ", array));
        // Output: [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]

        array = new []{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        shiftCount = 15;
        Rotate(ref array, shiftCount);
        Console.WriteLine(string.Join(", ", array));
        // Output: [6, 7, 8, 9, 10, 1, 2, 3, 4, 5]

        array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        shiftCount = -1;
        Rotate(ref array, shiftCount);
        Console.WriteLine(string.Join(", ", array));
        // Output: [2, 3, 4, 5, 6, 7, 8, 9, 10, 1]

        array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        shiftCount = -35;
        Rotate(ref array, shiftCount);
        Console.WriteLine(string.Join(", ", array));
        // Output: [6, 7, 8, 9, 10, 1, 2, 3, 4, 5]
    }

    private static void Rotate<T>(ref T[] array, int shiftCount)
    {
        T[] backupArray= new T[array.Length];

        for (int index = 0; index < array.Length; index++)
        {
            backupArray[(index + array.Length + shiftCount % array.Length) % array.Length] = array[index];
        }

        array = backupArray;
    }

Lo que es importante en este código es la fórmula con la que encontramos el nuevo valor de índice después de la rotación.

(index + array.Length + shiftCount% array.Length)% array.Length

Aquí hay un poco más de información al respecto:

(shiftCount% array.Length) -> normalizamos el valor del cambio para que esté en la longitud del array (ya que en un array con la longitud 10, el cambio de 1 u 11 es lo mismo, lo mismo ocurre con -1 y -11) .

array.Length + (shiftCount% array.Length) -> esto se hace debido a las rotaciones a la izquierda para asegurarnos de que no ingresamos en un índice negativo, sino que lo giramos hasta el final de la matriz. Sin él para una matriz con longitud 10 para el índice 0 y una rotación -1 entraríamos en un número negativo (-1) y no obtendríamos el valor del índice de rotación real, que es 9. (10 + (-1% 10) = 9)

index + array.Length + (shiftCount% array.Length) -> no hay mucho que decir aquí ya que aplicamos la rotación al índice para obtener el nuevo índice. (0 + 10 + (-1% 10) = 9)

index + array.Length + (shiftCount% array.Length)% array.Length -> la segunda normalización es asegurarse de que el nuevo valor de índice no salga de la matriz, sino que rote el valor al principio de la matriz. Es para rotaciones a la derecha, ya que en una matriz con longitud 10 sin ella para el índice 9 y una rotación 1 entraríamos en el índice 10, que está fuera de la matriz, y no obtendremos el valor del índice de rotación real es 0. ((9 + 10 + (1% 10))% 10 = 0)



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow