views:

276

answers:

6

for example, given a matrix:

1 2 3

4 5 6

7 8 9

if you are goint to swap row[0] and row[1], resulting matrix would be:

4 5 6

1 2 3

7 8 9

can you guys help me get a code in C for this?

A: 
temprow = row[1];
row[1] = row[0];
row[0] = temprow;
dash-tom-bang
i'm using 2d array. please help me:(
Using the right implementations of the matrix this could be right, but as a bare answer (without a discussion on the matrix implementation and the types of the variables above) it is very wrong. Details matter in c.
dmckee
If your going to be swapping rows, this is the kind of implementation that should be used anyway.
mathepic
What is the "right" implementation of a matrix? Details matter, but as the OP stated, he wanted to swap row[0] with row[1]. Just make temprow the same type and bang you're done.
dash-tom-bang
The OP also stated (eventually) that he is using plain old two dimensional arrays. And this *won't* work when the row type is `double[]` or similar because c does not support element copy assignment semantics for arrays.
dmckee
+6  A: 

The answer depends entirely on how your "matrix" is implemented, because the c language has no notion of such a thing.

Are you using two dimensional arrays?

double m[3][3];

Or something else?

Two dimensional arrays

You will have to move individual elements by hand.

for (i=0; i<ROWLENGTH; ++i){
  double temp;
  temp = m[r2][i];
  m[r2][i] = m[r1][i];
  m[r1][i] = temp;
}

(here r1 and r2 are ints that have been set to the two row you want to swap) or see James' memcpy implementation which may well be faster but requires a whole rows worth of temporary memeory.

Ragged Arrays

If this operation is very common and profiling reveals that it is consuming a lot of time, you might consider using a ragged array implementation of the matrix. Something like this:

double **m;
m = malloc(sizeof(double*)*NUMROWS);
/* put error checking here */
for (i=0; i<NUMROWS; ++i){
  m[i] = malloc(sizeof(double)*ROWLENGTH);
  /* error checking again */
}

The fun part about this structure is that you can still access it with the [][] notation, but the row swap operation becomes

double *temp;
temp = m[r2];
m[r2] = m[r1];
m[r1] = temp;

Ragged arrays have two disadvantages from your point of view (well, three 'cause of the memory management hassle): they require extra storage for the row pointers, and you can't use inline initialization.

Row-as-astructure

C does not support array assignments of the form;

double r[3], q[3] = { 1, 2, 3 };
r = q; /* ERROR */

but it does support by-value assignment semantics for structures. Which gives you the implementation that several people have suggested without explaining:

typedef struct { double r[ROWLENGTH] } row;
row m[NUMROWS] = { {1, 2, 3}, {4, 5, 6}, {7, 8 9}};

row temp = m[2];
m[2] = m[1];
m[1] = temp;

which is slick. It requires a whole row of memory, but if the compiler is any good is probably fast. The big disadvantage is that you can not address individual matrix elements with the [][] syntax anymore. Rather you write m[i].r[j];

Others

There are many, many other ways to implement a "matrix" in c, but they are mostly much more complicated and useful only in specialized situations. By the time you need them you'll be able to answer this questions for yourself in the context of each one.

dmckee
i'm using 2d array. please help me:(
THANK YOU VERY MUCH! SUCH A GREAT HELP!
thanks again! i'm using the 2d code. however, when i tried a matrix of 2x3, there's some error. third column or column[2] does not swap.
what i mean is the row elements on the last column does not swap
@user pay attention to the limits of the `for` loop. If your rows are 3 long the loop should run from 0 to 2, which is usually built with `for(i=0;i<3;++i)`. It is no uncommon for beginners to write `for(i=0;i<2;++i)` which won't work or `for(i=0;i<=2;++i)` which will, but looks weird (non-idiomatic) to c programmers.
dmckee
i got it, in the for loop. i<COLUMNLENGTH not i<ROWLENGTH since that it wont always be a square matrix and the number of rows and columns will always be dependent from the user.
+4  A: 
typedef int Row[3];
Row Matrix[3];

Row Temp;

memcpy(Temp, Matrix[0], sizeof(Row));
memcpy(Matrix[0], Matrix[1], sizeof(Row));
memcpy(Matrix[1], Temp, sizeof(Row));
James Curran
Nice. The best part here is that it works for *any* implementation with contiguous rows.
dmckee
Nice answer, good use of typedef to make the code more readable. But I'm afraid it most likely does not answer the OP, as I suspect it simply goes totally over his/her head.
mctylr
Thank you very much for answering. I am just new in C and we're not yet done discussing with memcpy
+2  A: 

I'd probably swap one element at a time to avoid using a lot of extra storage. If you're working primarily with things like graphics transforms where the matrices are typically 3x3 or 4x4, James Curran's approach is probably a bit better. If you are (or might be) working with really large matrices, this will save memory, and quite possibly run faster:

int x[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

for (int i=0; i<3; i++) {
    int temp = x[0][i];
    x[0][i] = x[1][i];
    x[1][i] = temp;
}
Jerry Coffin
thanks for answering. :) it helped me
+2  A: 

solve this your homework?

typedef struct {int m[3];} Row;
typedef int RowAccess[3];

main()
{
  Row tmp,row[]={{1,2,3},{4,5,6},{7,8,9}};
  RowAccess *rowa=row;
  tmp=row[0];
  row[0]=row[1];
  row[1]=tmp;
  /* easy access to matrix here: (is this what you want?) */
  rowa[0][0]=0;
  rowa[0][1]=1;
  ...
  return 0;
}
You should add some discussion here; the more so because this is a beginner type question. This trick works because of the assignment semantics of structures.
dmckee
Swapping looks nice. But this: `row[1].m[2] = ...` sucks. Hm, that's the point, isn't it?
Maciej Hehl
@Maciej a #define does help here
So it wasn't the point. You really meant the answer to be useful and not just a mischievous attempt to punish the OP? I wouldn't guess.
Maciej Hehl
A: 

Hy! this is my first post on stack overflow, I know it's pretty long, hope I won't get banned!

Probably one of the most elegant approaches would be using a function that swaps the two received arguments - using it to swap matrix components. Let's say somethig like swap(a,b). As many have already said, we should consider using a auxiliary variable

auxiliary = a ;
a = b ;
b = auxiliary ; 

Recently, I picked up a new method, which I found impressing, using bitwise XOR operation (http://en.wikipedia.org/wiki/Xor) thus a auxiliary is not needed

 a ^= b ;
 b ^= a ;
 a ^= b ;

You can easily use this operation to swap two elements ( a and b ) - I belive this is off topic, but I insisted on this idea because I found it pretty interesting. Finally, answering your question, you could use let's say

int swap (int *a , int *b){
    (*a)^=(*b);
    (*b)^=(*a);
    (*a)^=(*b);
    return 0; 
}

while having a matrix declared as

#define ROW_COUNT 5
#define COLUMN_COUNT 5
....
int a[ROW_COUNT][COLUMN_COUNT];

You can use your the XOR way the swap the rows, firstly identifyng the elements needed to be swapped ( according to row index, as you already said )

printf("\nSwap Row: "); scanf("%d", &swp1) ; // first row index
printf("With Row: "); scanf("%d", &swp2);    // second row index

for (j = 0 ; j < COLUMN_COUNT ; j++){
     swap(  &a[swp1][j] , &a[swp2][j] );   
}

I hope this will be usefull in your further practice.

Also try this example, I'm sure you'll understand the whole idea much better afterwards (don't forget matrix index starts at 0 !)

#include "stdio.h"
#include "conio.h"

#define ROW_COUNT 5
#define COLUMN_COUNT 5



int swap (int *a , int *b){
        (*a)^=(*b);
        (*b)^=(*a);
        (*a)^=(*b);
        return 0; 

}        

int main(){
    int i, j ;
    int swp1, swp2 ; 
    int a[ROW_COUNT][COLUMN_COUNT];

    // Create ( ROW_COUNT X COLUMN_COUNT ) random matrix

    for (i = 0 ; i < ROW_COUNT ; i++ ) 
        for (j = 0 ; j < COLUMN_COUNT ; j++ )  a[i][j] = rand();

    // Display matrix before row swap

    for (i = 0 ; i < ROW_COUNT ; i++ ){ 
        for (j = 0 ; j < COLUMN_COUNT ; j++ )  printf("%d\t",a[i][j]);
        printf("\n");     
    }

    // Elements to be swapped

    printf("\nSwap Row: "); scanf("%d", &swp1) ;  // first row index
    printf("With Row: "); scanf("%d", &swp2);     // second row index

    // Swapping right here

    for (j = 0 ; j < COLUMN_COUNT ; j++){
         swap(  &a[swp1][j] , &a[swp2][j] );   
    }


    // Display once again   

    printf("\n");
    for (i = 0 ; i < ROW_COUNT ; i++ ){ 
        for (j = 0 ; j < COLUMN_COUNT ; j++ )  printf("%d\t",a[i][j]);
        printf("\n");     
    }   



    getch();            
 return 0;   
} 
Dan