Shift through an array sequentially in C

Viewed 77

I have a matrix that I am trying to "count" through by shifting the first row to the left n number of times until it is in its original position, at which point I would shift the second row to the left once, then go through the entire first row again, shift the second row once, so on and so forth until the second row is in its original position, at which point the third row would shift once and we start all over again.

For example:

0 1 2     1 2 0     2 0 1     0 1 2     1 2 0     2 0 1   a few     0 1 2     1 2 0
0 1 2 ==> 0 1 2 ==> 0 1 2 ==> 1 2 0 ==> 1 2 0 ==> 1 2 0 ==> ==> ==> 0 1 2 ==> 0 1 2 ... ... ...
0 1 2     0 1 2     0 1 2     0 1 2     0 1 2     0 1 2    more     1 2 0     1 2 0

all the way until every possible combination has been reached. In an MxN matrix this should give me N^M possibilities. The actual matrix I am working with is much larger than this one so I am trying to avoid 250+ nested loops.

I already have the shift method:

static inline void shift(uint8_t *row){ //a row from a 2D Array
  int a, temp;
  int b = sizeof(row);
  temp = row[0];
  for(a = 0; a < b; a++){
    channel[a] = channel[a+1];
  }
  channel[b] = temp;
}

Any help would be greatly appreciated.

2 Answers

Your shift() function can be improved this way:

static void shift(uint8_t* row, size_t row_size) {
  uint8_t temp = row[0];
  for (size_t i = 0; i < row_size - 1; i += 1) {
    row[i] = row[i + 1];
  }
  row[row_size - 1] = temp;
}
// P.S.: row_size must be at least 1, or the function will break

Really nice question, I appreciate you for this. I am doing the question in very basic way for better understanding, must read all line comments to understand the program. I am tested this on TurboC by printing matrix after each shift and its working according to me. If you want some improvement or it require some change to reach your requirement then you may try or just give a comment.All the best.

#include<stdio.h>

#define MAX 50

void shift(int *rowToShift, int size){
//To circular shift the row
 int i,tmp = rowToShift[0];
 for(i=0;i<size-1;i++){
    rowToShift[i] = rowToShift[i+1];
 }
 rowToShift[size-1] = tmp;
}

void main(){

 //I am just initilizing matrix with your initial data, I tested on this
 int mat[MAX][MAX] = {{0,1,2},{0,1,2},{0,1,2}};
 int row=3,col=3;//you may get it from user

 // We keep it always on row we shifting
 int currentRow=0;

 /*This tracker helps to track which row incremented
 how many times*/
 int shiftTracker[MAX];
 while(currentRow < row){

  //Shift current row to 1 left, (circular left as you ask)
  shift(mat[currentRow],col);

  shiftTracker[currentRow]++;

  if(shiftTracker[currentRow] == row){
   /*if current row shift is completed, means
     Now again in original condition*/

   shiftTracker[currentRow] = 0; //Reset traker for current row

   currentRow++;//Moving to Next row

   if(currentRow == row){
   //if all rows are completed
    break;
   }
  }
  else if(shiftTracker[currentRow] < row && currentRow != 0){
   //if all rows not completed and currentRow not on 0
   currentRow = 0;
  }
 }
}
Related