Сдвиг массива последовательно в C - PullRequest
2 голосов
/ 31 марта 2020

У меня есть матрица, которую я пытаюсь «посчитать», сдвигая первую строку влево n раз, пока она не окажется в исходном положении, и в этот момент я бы сдвинул второй ряд влево один раз, затем go снова через весь первый ряд, сдвиньте второй ряд один раз, и так далее, и так далее, пока второй ряд не будет в исходном положении, после чего третий ряд будет сдвигаться один раз, и мы начнем все сначала.

Например:

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

до тех пор, пока не будет достигнута любая возможная комбинация. В матрице MxN это должно дать мне N ^ M возможностей. Фактическая матрица, с которой я работаю, намного больше этой, поэтому я стараюсь избегать 250+ вложенных циклов.

У меня уже есть метод сдвига:

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;
}

Любая помощь будет с благодарностью.

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Действительно хороший вопрос, я ценю вас за это. Я делаю вопрос очень простым способом c для лучшего понимания, я должен прочитать все строчные комментарии, чтобы понять программу. Я проверял это на Turbo C, печатая матрицу после каждой смены, и она работала в соответствии со мной. Если вы хотите некоторого улучшения или вам нужно внести некоторые изменения, чтобы удовлетворить ваши требования, вы можете попробовать или просто дать комментарий. Все лучшее.

#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;
  }
 }
}
1 голос
/ 31 марта 2020

Ваша функция shift() может быть улучшена следующим образом:

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
...