Home > Mobile >  Move All Columns Of A Matrix To The Left By One C
Move All Columns Of A Matrix To The Left By One C

Time:02-16

my problem is to take a matrix mat of rowcol length, and move each column within it one position to the left. For example if i have a 3x3 matrix like this:

4 5 2
6 7 3 
3 4 6

the result should must be like this:

5 2 4
7 3 6
4 6 3

I can't get the method to work, how many times I do it, does anyone have any ideas?

Below my code:

for(int i = rowcol - 1; i > 0; i--)
            for(int j = 0; j < rowcol; j  ) {
                if(i == 0) swap(mat[j][rowcol - 1], mat[j][i]);
                swap(mat[j][i], mat[j][i-1]);
            }

CodePudding user response:

The standard library has an algorithm to do what you're asking: std::rotate. The following example rotates everything right one column.

#include <iostream>
#include <algorithm>

int main()
{
    int arr[][3] = {
        { 1,2,3 },
        { 4,5,6 },
        { 7,8,9 }
    };

    for (auto& row : arr)
    {
        std::rotate(row, row 2, row 3);
    }

    for (auto& row : arr)
    {
        for (auto x : row)
            std::cout << x << ' ';
        std::cout << '\n';
    }
}

Output

3 1 2 
6 4 5 
9 7 8 

Obviously the conditions of your matrix access to individual rows can be (and is likely) different than the above trivial example, but nonetheless, the concept is still the same. I leave it to you to play with for learning how to do it "left" (it won't be hard *).

hint: std::rotate(row, row 1, row 3);

CodePudding user response:

Here's my updated solution. It's even easier than the original one I posted a few minutes earlier.

Basically, for each row:

  • Save off the value in the first column
  • Shift all the values (starting at column 1) in the row by one to the left.
  • The last value in the row is the previously saved variable from the first step

Code:

for (size_t row = 0; row < rowcol; row  ) {
   int tmp = mat[row][0];
   for (size_t col = 1; col < rowcol; col  ) {
       mat[row][col-1] = mat[row][col];
   }
   mat[row][rowcol-1] = tmp;
}

CodePudding user response:

What about as follows ?

  for ( auto ui = 0u ; ui < rowcol ;   ui )
    for ( auto uj = 1u ; uj < rowcol ;   uj )
      std::swap(mat[ui][uj-1], mat[ui][uj]);

The following is a full compiling example

#include <iostream>
    
static constexpr std::size_t  rowcol = 3u;

void printMat (int mat[rowcol][rowcol])
{
  for ( auto ui = 0u ; ui < rowcol ;   ui ) {
    for ( auto uj = 0u ; uj < rowcol ;   uj )
      std::cout << mat[ui][uj] << ' ';

    std::cout << std::endl;
  }

  std::cout << std::endl;
}

int main()
{
  int mat[rowcol][rowcol] { {4, 5, 2}, {6, 7, 3}, {3, 4, 6} };

  printMat(mat);

  for ( auto ui = 0u ; ui < rowcol ;   ui )
    for ( auto uj = 1u ; uj < rowcol ;   uj )
      std::swap(mat[ui][uj-1], mat[ui][uj]);

  printMat(mat);
}

CodePudding user response:

Your logic is correct except, you're actually shifting the columns of the matrix one position to the right, not left. Not only that, the (i==0) condition is not required.

Replace the backward iteration with forward iteration and get rid of the conditional statement and you're good to go. Here's the modified code:

for(int i = 0; i < rowcol-1; i  )
        for(int j = 0; j < rowcol; j  ) {
            // if(i == 0) swap(mat[j][rowcol - 1], mat[j][i]);
            swap(mat[j][i], mat[j][i 1]);
        }

Basically your logic is similar to Bubble Sort. You were bubbling the final column towards the beginning of the matrix by shifting all other columns rightward.

I inverted it by making it so that we are bubbling the first column towards the end instead. Feel free to ask any questions.

  • Related