1

I have a 6 x 6 matrix, and I am storing its values in a one dimensional array of size 36. I want to rearrange it so that the rows are the columns and the columns are the rows. My method is trying to copy the values into another array, but sorted properly. I am trying a for loop:

    for (int i = 0; i < 6; ++i){
        copyArray[i]= array[i*6];
    }

This works fine for the first new row made up of the first column, but how do I continue to do all of them? I have tried nested for loops but cannot come up with the proper algorithm using iterators. I could do this manually, but would like to have this done by code.

I am coding in C++, but if anyone can do it in a similar language that would be fine. I feel this is a math problem.

The Question: How do I solve for switching out the rows and columns? (Example: if I am denoting the first rows and columns as 0, in a 6x6 matrix, then both rows and columns go from 0 to 5. Therefore, by switching rows and columns, the value in row 2, column 5 would be switched with the value in row 5, column 2.)

JCoder
  • 189
  • 1
  • 3
  • 17

5 Answers5

2

Couldn't you just use a nested for loop and do something like this?

for (int i = 0; i < 6; ++i)
    for (int j = 0; j < 6; ++j)
        copyArray[i*6+j]= array[j*6+i];

Here's a test program you can run to show it works:

#include <stdio.h>

int main()
{
    int array[36] = {1,1,1,1,1,1,
                     2,2,2,2,2,2,
                     3,3,3,3,3,3,
                     4,4,4,4,4,4,
                     5,5,5,5,5,5,
                     6,6,6,6,6,6};
    int copyarray[36];

    for (int i = 0; i < 6; ++i)
        for (int j = 0; j < 6; ++j)
            copyarray[i*6+j]= array[j*6+i];

    for (int i = 0; i < 36; ++i)
    {
        if (i % 6 == 0)
            printf("\n");

        printf("%d ", array[i]);

    }

    printf("\n");
    printf("\n");

    for (int i = 0; i < 36; ++i)
    {
        if (i % 6 == 0)
            printf("\n");

        printf("%d ", copyarray[i]);
    }

    return 0;
}

Output:

1 1 1 1 1 1 
2 2 2 2 2 2 
3 3 3 3 3 3 
4 4 4 4 4 4 
5 5 5 5 5 5 
6 6 6 6 6 6 


1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6
Gillespie
  • 5,780
  • 3
  • 32
  • 54
  • Thanks, I'll try it out. That's exactly what I was trying to do but couldn't figure out the right variable/mathematical operator combinations. Complex algebra feels like ancient knowledge. – JCoder Dec 07 '14 at 23:38
  • All I did to figure out the two formulas in `[]` was to list out which values I wanted them to be and then put the pattern in terms of 6, and then finally in terms of `i` and `j`. For example, we want the one on the left to follow the pattern `0 1 2 3 4 5 6 7 8 9 10 11 12 ... 35` and we want the one on the right to follow the pattern `0 6 12 18 24 30 1 7 13 19 25 31 ... 35`. Next we put it in terms of `6`: the first pattern becomes `(0*6+0) (0*6+1) ... (5*6+5)` and the second pattern becomes `(0*6+0) (1*6+0) (2*6+0) ... (5*6+5)`. Last we can put it in terms of `i` and `j` as seen. – Gillespie Dec 08 '14 at 15:19
0
for( int i=0;i<6;i++)
   for( int j=0;j<6;j++)
      {         }//You can do whatever you want on original matrix here

Let's say that you want "transpose of matrix" and do some processing .Basically switch i and j

 for( int j=0;j<6;j++)   // replaceed i with j
   for( int i=0;i<6;i++)
      {              }//You can do whatever you want on transpose matrix here
Muhammet Ali Asan
  • 1,486
  • 22
  • 39
  • Yes, I was trying to do this, but couldn't figure out the variable/operator sequence for the switch. It was the algebra that was bugging me, but thanks! – JCoder Dec 07 '14 at 23:41
  • 1
    @JCoder: BTW: After you have accepted one of the answers (whichever helped you most), you will have 16 rep (2 more), and thus enough to upvote whichever answers helped you (also on your old questions, if you want to re-visit them). Though don't just upvote an answer because someone tried to help, but because the answer itself is helpful. – Deduplicator Dec 07 '14 at 23:43
  • @JCoder you should accept one of the answer and upvote – Muhammet Ali Asan Dec 08 '14 at 07:46
0

You should keep your one-D array inside a class.
Then you can swap the dimensionality of the data without actually moving it.

class MySwapableArray
{
     bool  normal;
     int   array[36];


     public:
         int& operator()(int x, int y)
         {
              int  h = normal ? x : y;
              int  v = normal ? y : x;

              return array[h*6+v];
         }
         void swapRowsAndColumns()
         {
             normal = ! normal;
         }
 };

If you want to use operator[] like A[x][y] then see: How to overload array index operator for wrapper class of 2D array?

Community
  • 1
  • 1
Martin York
  • 257,169
  • 86
  • 333
  • 562
0

A template for doing so.

template<class X> std::unique_ptr<typename std::pointer_traits<X>::element_type[]>
transpose(const X& p, int x, int y) {
    using T = std::pointer_traits<X>::element_type;
    std::unique_ptr<T[]> r = new T[x*y];
    for(int a = 0; a < x; ++a)
        for(int b = 0; b < y; ++b)
            r[x*a+b] = p[y*b+a];
    return r;
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
0

If you want to avoid a double-for loop, you should be able to do it mathematically with something like

for (int i = 0; i < 36; ++i) {
    copyarray[6 * (i % 6) + i / 6] = array[i]
}

Basically, 6 * (i % 6) aligns you to the right row in the transposed matrix, and the i / 6 (ab)uses integer division to translate the column value into a row value. floor (i / 6.0) is more correct if you can live with the clutter.

Candlemancer
  • 91
  • 1
  • 4