JackV
JackV

Reputation: 218

Function to left shift a 2D array in C

I'm writing a function within my program to left shift all the numbers in an array that was passed to the function. An example is:

1 2 3 
4 5 6

becomes

2 3 4
5 6 1

My code is:

void LeftShift(int array[][N])/*Get the array from main*/
{
    int r, c, temp;
    for(r = 0; r < M; r++) { //Start at row 0 and add one each time
      for(c = 0; c < N; c++) { //Start at column 0 and add one each time
         if(c > 0) {
            array[r][c] = array[r][c-1]; //Number is moved over one if its not the first column
         }
         else if(c == 0 && r > 0) { //If its first column but not first row
            array[r][c] = array[r-1][N-1];//Move number up one row and too last column
         }
         else {
         temp = array[r][c];//If its first column and first row store value in temp
        }
      }
    }
    array[M-1][N-1] = temp;//Put temp value at end of array
}

When I print this out all I get is the first number from the original array in every spot in the array. M is defined at the top to be 6 and N is defined to be 5. After this runs, I call a function that prints out the new array and all I get is the first value 30 times in an array.

Upvotes: 0

Views: 7046

Answers (3)

Luis Colorado
Luis Colorado

Reputation: 12668

You can go throw the array, having a pointer following the last place you visited, and moving the elements, as in this example:

#define nrows 4
#define ncols 4

int array[nrows][ncols] = {
    { 1, 2, 3, 4, },
    { 5, 6, 7, 8, },
    { 9, 10, 11, 12, },
    { 13, 14, 15, 16, },
};

int main()
{
    int row, col;
    int saved_int;
    int *p = &saved_int;

    /* rotate elements */
    for(row = 0; row < nrows; row++)
        for (col = 0; col < ncols; col++) {
            *p = array[row][col];
            p = &array[row][col];
        } /* for */
    *p = saved_int;

    /* print matrix */
    for (row = 0; row < nrows; row++) {
        for (col = 0; col < ncols; col++)
            printf( "%s%d",
                    (col ? "\t" : ""),
                    array[row][col]);
        printf("\n");
    } /* for */
    return 0;
} /* main */

Upvotes: -1

M.M
M.M

Reputation: 141574

2-D arrays are contiguous in memory, so you can iterate over it as if it were a 1-D array:

void left_rotate(int array[][N])
{
    int *flat = (int *)array;
    int temp = flat[0];

    for ( size_t i = 1; i < M*N; ++i )
        flat[i-1] = flat[i];

    flat[M*N-1] = temp;

}

The for loop could also be replaced with a single block move:

memmove(&flat[0], &flat[1], (M*N-1) * sizeof *flat);

Upvotes: 4

user3386109
user3386109

Reputation: 34829

array[r][c] = array[r][c-1];

should be

array[r][c-1] = array[r][c];

Likewise for the row shift.

Upvotes: 2

Related Questions