'Move All Columns Of A Matrix To The Left By One C++

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


Solution 1:[1]

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

Solution 2:[2]

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

Solution 3:[3]

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

Solution 4:[4]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 max66
Solution 4 Harsh Motwani