Search code examples
c#arraysshiftcircular-buffer

How to shift one array element wrap around?


I am trying to write a function which iterates through an array and when it finds a certain type of value it will shift it to the right a defined number of places.

I know how to shift elements by temporarily storing a value, shifting the right side elements to the left and then writing the temporary value in the correct place.

The bit I am struggling with is if the certain character appears near the end of the array I need it to wrap around and continue from the start of the array, so is circular.

So an array shifting, for example, capital letters to the right 3 places and special characters to the left 1 place:

{ M, y, N, a, m, e, P} becomes...
{ y, M, P, a, N, m, e}

To shift an element of 8 to the right 3 places I have below, but this only works if 8 appears earlier than 3 elements from the end of the array and will not wrap around.

input array:

{0, 1, 2, 3, 4, 5, 6, 7, **8**, 9}

desired output:

{0, **8**, 1, 2, 3, 4, 5, 6, 7, 9}
int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

for (int i = array.Length - 1; i >= 0; i--) 
{
    if (array[i] == 8) 
    {
        int temp = array[i];
        int j = 0;
        for (j = i; j < i + 3; j++) 
        {
            array[j] = array[j + 1];
        }
        array[j] = temp;
    }
}

Solution

  • Just use modulo arithmetic so that instead of writing to the element at index j as you shift, instead write to the element at index j % array.Length. Thusly:

    public void FindAndShift<T>(T[] array, T value, int shift) {
        int index = Array.IndexOf(array, value);
        int shiftsRemaining = shift;
        for(int currentPosition = index; shiftsRemaining > 0; shiftsRemaining--) {
            array[currentPosition % array.Length] = array[(currentPosition + 1) % array.Length];
        }
        array[(index + shift) % array.Length] = value;
    }
    

    I have excluded error checking.