Answer 2D11

#include <stdio.h>
#include <stdlib.h>

#define NUMCOLS 11
#define NUMROWS 4

/* Puzzle D11 -- reverse the order of the elements in a 2D array */

/* Put the elements of an array in reverse order. */
int reverse2D( int nrows, int ncols, int x[nrows][ncols] )
{
  int r, c, temp;
  int swapR, swapC;  /* the location (r,c) is sent to */
  
  /* Visit elements in row major order */
  for ( r=0; r<nrows/2; r++ )
  {
    swapR = nrows - r - 1;
    for ( c=0; c<ncols; c++ )
    { 
      swapC = ncols - c - 1;
      temp = x[r][c];
      x[r][c] = x[swapR][swapC];
      x[swapR][swapC] = temp;
    }
  }  
  
  /* With an odd number of rows, the middle row is a special case */
  if ( nrows%2 == 1)
  {
    swapR = nrows/2;
    for ( c=0; c<ncols/2; c++ )
    { 
      swapC = ncols - c - 1;
      temp = x[r][c];
      x[r][c] = x[swapR][swapC];
      x[swapR][swapC] = temp;
    }
  }
}

void print2DArray ( int nrows, int ncols, int x[nrows][ncols] )
{
  int r, c;  /* row and column indexes for the array */

  /* Print elements in row major order */
  for ( r=0; r<nrows; r++ )
  {
    for ( c=0; c<ncols; c++ )
      printf("%3d ", x[r][c]  );
    printf("\n");
  }
}

void fill2DArray ( int nrows, int ncols, int x[nrows][ncols] )
{
  int r, c, val = 0;
  for ( r=0; r<nrows; r++ )
  {
    for ( c=0; c<ncols; c++ )
       x[r][c] = val++ ;
  }
}

int main(int argc, char *argv[])
{
  int x[NUMROWS][NUMCOLS];
  fill2DArray( NUMROWS, NUMCOLS, x );

  printf("Original:\n");
  print2DArray( NUMROWS, NUMCOLS, x );

  printf("\n\nReversed:\n");
  reverse2D( NUMROWS, NUMCOLS, x );
  print2DArray( NUMROWS, NUMCOLS, x );

  system("pause");
  return 0;
}

Comments: Conceptually there are two "fingers" pointing to elements of the array. One finger starts on the first element (the upper left), the other finger starts on the last element (the lower right), and the two fingers move toward each other (in raster order) swapping elements as they go. Dealing with an odd number of rows is fairly tricky. It is hard to get this correct the first time.

Another way to do this is to regard the elements in memory as a 1D array, and to reverse those elements in a 1D fashion:

int reverse2Das1D( int nrows, int ncols, int x[nrows][ncols] )
{
  int j, temp ;
  for ( j=0; j<( nrows*ncols )/2; j++ )
  {
     temp    = x[0][j] ;
     x[0][j] = x[0][ nrows*ncols-1-j ] ;
     x[0][ nrows*ncols-1-j ] = temp ;
  }
}

The above function "cheats" by treating the entire array as a single row 0. A programming language that does bounds checking (such as Java) would not let you do this.



Back to Puzzle Home