如何交换矩阵中的两行(在 C 语言中)?

发布于 2024-09-15 07:10:29 字数 175 浏览 2 评论 0 原文

例如,给定一个矩阵:

1 2 3

4 5 6

7 8 9

如果你要交换 row[0] 和 row[1],结果矩阵将是:

4 5 6

1 2 3

7 8 9

你们可以帮忙吗我能得到一个 C 代码吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

心不设防 2024-09-22 07:10:29

答案完全取决于你的“矩阵”是如何实现的,因为c语言没有这样的概念。

您使用的是二维数组吗?

double m[3][3];

或者其他什么?

二维数组

您必须手动移动各个元素。

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

(这里 r1r2 是已设置为要交换的两行的整数)或参见 James 的 memcpy 实现 可能会更快但需要一整行的临时内存。

参差不齐的数组

如果此操作非常常见,并且分析表明它消耗大量时间,则您可以考虑使用矩阵的参差不齐的数组实现。像这样的事情:

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 */
}

这个结构的有趣之处在于,您仍然可以使用 [][] 表示法访问它,但是行交换操作变得

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

不规则数组从您的角度来看有两个缺点(嗯,三个导致内存管理麻烦的原因):它们需要额外的存储空间来存储行指针,并且不能使用内联初始化。

行结构

C 不支持以下形式的数组赋值;

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

但它确实支持结构的按值赋值语义。这为您提供了几个人建议的实现,但没有解释:

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;

这很巧妙。它需要一整行内存,但如果编译器好的话可能会很快。最大的缺点是您无法再使用 [][] 语法来寻址各个矩阵元素。相反,你可以写 m[i].r[j];

其他

在c中实现“矩阵”的方法有很多很多,但它们大多更加复杂并且仅在特殊情况下有用。当您需要它们时,您将能够在每个问题的背景下自己回答这些问题。

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.

甜警司 2024-09-22 07:10:29
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));
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));
风尘浪孓 2024-09-22 07:10:29

我可能会一次交换一个元素,以避免使用大量额外的存储空间。如果您主要处理诸如图形变换之类的事情,其中​​矩阵通常为 3x3 或 4x4,那么 James Curran 的方法可能会更好一些。如果您正在(或可能正在)处理非常大的矩阵,这将节省内存,并且很可能运行得更快:

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

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;
}
朮生 2024-09-22 07:10:29

解决这个你的作业吗?

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

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;
}
永不分离 2024-09-22 07:10:29

嘿!这是我关于堆栈溢出的第一篇文章,我知道它很长,希望我不会被禁止!

也许最优雅的方法之一是使用一个函数来交换两个接收到的参数 - 用它来交换矩阵分量。比如说swap(a,b)
正如许多人已经说过的,我们应该考虑使用辅助变量

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

最近,我采用了一种新方法,我发现它令人印象深刻,使用按位异或运算(http://en.wikipedia.org/wiki/Xor)因此不需要辅助

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

您可以轻松地使用此操作来交换两个元素( a 和 b ) - 我相信这是题外话,但我坚持这个想法,因为我发现它很有趣。
最后,回答你的问题,你可以使用假设,

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

同时将矩阵声明为

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

你可以使用 XOR 方式交换行,首先确定需要交换的元素(根据行索引,正如你已经说过的)

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

我希望这对你进一步的练习很有用。

也试试这个例子,我相信你之后会更好地理解整个想法(不要忘记矩阵索引从 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;   
} 

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;   
} 
夏日落 2024-09-22 07:10:29
temprow = row[1];
row[1] = row[0];
row[0] = temprow;
temprow = row[1];
row[1] = row[0];
row[0] = temprow;
離人涙 2024-09-22 07:10:29

有一个名为 swap 的函数:

#include <algorithm>
int A[][] = {{1,2,3},{4,5,6},{7,8,9}};
swap(A[0],A[2]); //swaps first and last row

There is a function called swap:

#include <algorithm>
int A[][] = {{1,2,3},{4,5,6},{7,8,9}};
swap(A[0],A[2]); //swaps first and last row
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文