2

Trying to create two functions (one to swap columns and one to swap rows) of matrices in one-dimensional arrays. Obviously, they'd be structurally similar.

void col_swap(int a[], int col1, int col2, int colSize, int rowSize) {
  int d[size];
  int space = col2 - col1;
  for (int i = 0; i < rowSize; i++) {
    for (int j = 0; j < colSize; j++) {
      if (i == (col1 - 1) || i == (j * (col1-1))) {
        d[i+space] = a[i];
      } else if (i == (col2 - 1) || i == (j * (col2-1))) {
        d[i-space] = a[i];
      } else {
        d[i] = a[i];
      }
    }
    printf("%d  ", d[i]);
      if ((i+1) % colSize == 0) {
          printf("\n");
      }
  }
}

Yes, the matrix must be in a one-dimensional array. This doesn't work fully either.

EDIT: COL1 and COL2 are not "the first column of matrix" and "the second column of matrix", respectively. They are any two columns of a matrix that we want to switch.

void row_swap(int a[], int row1, int row2, int rowSize, int colSize) {
  for (int i = 0; i < colSize; i++) {
    int temp = a[i*rowSize+row1];
    a[i*rowSize+row1] = a[i*rowSize+row2];
    a[i*rowSize+row2] = temp;
  }
  for (int i = 0; i < size; i++) {
    if (i % colSize == 0) {
      printf("\n");
    }
    printf("%d ", a[i]);
  }
}

I have the row_swap function as above but when I give it a matrix

1, 4,
2, 3,
3, 2,
4, 1

It returns

1, 3
2, 4
3, 1
4, 2
Briehn
  • 45
  • 1
  • 1
  • 7
  • The `c` masters can correct me here, but I'm pretty sure a two dimensional array NxM looks exactly the same in memory as a NxM dimension single dimension array - and hence can be accessed in both ways (single bracket or double bracket, within dimensions). Also, what doesn't work, what do you suspect, etc? – kabanus Oct 30 '17 at 16:44
  • @kabanus you're about to be corrected: You're right for the first part, but your conclusion is wrong, [see this question](https://stackoverflow.com/questions/6290956/one-dimensional-access-to-a-multidimensional-array-well-defined-c). Still I wonder what reason one could have to use a 1d array for storing a matrix. –  Oct 30 '17 at 16:45
  • @FelixPalmen Thanks. Is this enforced in the compiler? I didn't know `C` compilers could be that strict. – kabanus Oct 30 '17 at 16:46
  • @kabanus no, and that makes it **more** problematic, like a lot of C code that could lead to undefined behavior ;) –  Oct 30 '17 at 16:47
  • @FelixPalmen Ahh, that's what makes it so lovable. – kabanus Oct 30 '17 at 16:47
  • @kabanus it boils down to a strict aliasing violation (see answer in my linked question) -- so a lot of code would "get away with it", but it's still strictly speaking wrong and you *could* probably construct a case where the optimizer would compile it to wrong code. –  Oct 30 '17 at 16:50

2 Answers2

1

This is much easier than you think it would be.

So you want to swap col1 and col2 and here the matrix has rowsize number of rows and colsize number of columns.

void col_swap(int a[], int col1, int col2, int colSize, int rowSize) {
  for(int i=0;i<rowSize;i++){
    int t=a[i*colSize+col1];
    a[i*colSize+col1]=a[i*colSize+col2];
    a[i*colSize+col2]=t; 
  }
}

Just think what is different here. We have just calculate the logic clearly for the position. Then everything is same as standard swapping.

More struturally you can do this:-

void swap(int *a,int*b)
{
    int t=*a;
    *a=*b;
    *b=t;
}
void col_swap(int a[], int col1, int col2, int colSize, int rowSize) {
  for(int i=0;i<rowSize;i++){
    swap(&a[i*colSize+col1],&a[i*colSize+col2]); 
  }
}

The rowswapping would be same. It is similar to column swapping if you consider row as columns and vice versa.

Secondly, why do you want to complicate things by making using a 2d array out of a 1d array?

This is hard to use in production level code or more specifically softwares. Why not use the 2d array itself? You should use that instead of doing this.


What was the approach?

After reading the question, I just used paper to get an idea of what is that I want to do and how it maps from 2d array to 1d array. That helps alot of time. And then first coded the first solution. I could see that I can reuse the swapping part in case of Row swapping too. So I take it out and put it in a different function swap.

Sample input output example:

int a[]={1,2,3,4,5,6,7,8,9,10,11,12};
    col_swap(a,1,2,3,4);

// 1 2 3 
// 4 5 6 
// 7 8 9 
// 10 11 12

// 1 3 2 
// 4 6 5 
// 7 9 8 
// 10 12 11

Again if you consider:

col_swap(a,0,2,3,4); on the same array results in

// 3 2 1
// 6 5 4
// 9 8 7
// 12 11 10

I have used 0-indexing in the code. So be careful when you give input columns.

Also the other function would be:-

void row_swap(int a[], int row1, int row2, int colSize, int rowSize) {
  for(int i=0;i<colSize;i++){
    swap(&a[colSize*row1+i],&a[row2*colSize+i]); 
  }
}
Community
  • 1
  • 1
user2736738
  • 30,591
  • 5
  • 42
  • 56
  • Thank you for the response, but it wasn't really what I was looking for. Here's where I think I got you mistaken. The parameters col1 and col2 are not "the first column" and "the second column". They're any 2 columns of a matrix that we want to switch. So whenever we cycle through the original matrix, we have to see if the number is in the correct column, then switch it with the number in the other column. The reason why it's a 1D array is b/c this is an assignment for a class. – Briehn Oct 30 '17 at 17:16
  • I'm pretty sure there should be a check to see if the number is in the column that we're trying to swap. For example, if we have a 4x3 matrix, and we wanted to swap columns 2 and 3, we'd have to make sure we don't swap values in columns 1 and 4 with anything; which I think happens in your code. (don't have the tools to check right now, so this is just going off of what I'm seeing) – Briehn Oct 30 '17 at 17:27
  • Yeah, haha. Sorry, I was just confused a little bit but it's working now. Thank you. – Briehn Oct 30 '17 at 17:53
  • If I want to swap the rows now, would I just replace every colSize with rowSize and vice versa? Or is it not that simple... – Briehn Oct 30 '17 at 17:53
  • I've encountered a problem with the row swapping (I've edited the main post to show the function and the results) – Briehn Oct 30 '17 at 18:02
0

If you are using C99, then pointers to Variable Length Arrays can make the indexing much easier:

void col_swap(int a[], int col1, int col2, int colSize, int rowSize)
{
    // Cast 'a' to a pointer to a variable length array of size 'colSize'
    int (*a2d_matrix)[colSize] = (int (*)[colSize])a;

    // Now we can index into a (through a2d_matrix) as if it really is
    // a 2 dimensional matrix
    for(int r = 0; r < rowSize; r++)
    {
        int temp = a2d_matrix[r][col1];
        a2d_matrix[r][col1] = a2d_matrix[r][col2];
        a2d_matrix[r][col2] = temp; 
    }
}

I use this method often. Note that this probably works in C11 and greater, however Variable Length Arrays were made optional in the C11 standard. So check your compiler support of optional C11 features. All major vendors support VLAs in C11 as far as I know.

mshildt
  • 8,782
  • 3
  • 34
  • 41
  • This as well violates strict aliasing. You *can* run into bad issues with such casts. –  Oct 30 '17 at 17:20
  • @FelixPalmen I actually asked [this question](https://stackoverflow.com/questions/25036997/is-it-safe-to-cast-a-heap-allocated-pointer-to-a-pointer-to-a-vla) some time ago about this being well defined, and after various answers and discussion the consensus was this this did not violate strict aliasing. I'm reading through your linked answer though which seems to indicate to the contrary... – mshildt Oct 30 '17 at 17:22
  • @FelixPalmen Perhaps you could add an answer to the question I just referenced if you think the accepted answer is incorrect? I would appreciate it. – mshildt Oct 30 '17 at 17:24
  • It's hard to construct something that will fail for a construct like this, so it's mostly of academic interest, but I think the case with an allocated object is different -> it doesn't have a declared type (therefore doesn't have an array type). The question you linked might be a corner case receiving a **lot** of discussion if you add the [tag:language-lawyer] tag :) –  Oct 30 '17 at 17:28