【问题标题】:how do you swap two rows in a matrix (in C)?你如何交换矩阵中的两行(在 C 中)?
【发布时间】:2010-08-23 18:21:27
【问题描述】:

例如,给定一个矩阵:

1 2 3

4 5 6

7 8 9

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

4 5 6

1 2 3

7 8 9

你们能帮我弄个 C 代码吗?

【问题讨论】:

  • 这是作业吗? (请标记)
  • 是作业吗?你的矩阵是如何定义的?你知道如何交换两个 int 变量的值吗?你知道C语言中的循环吗?表现出一些努力,它会得到回报:)。
  • 这实际上是我的作业。这是我不知道如何解决的唯一矩阵运算。矩阵是 [100][100] 但行和列由用户定义。实际上我已经完成了交换行、添加行、矩阵添加、mult。等
  • 请分享您当前的最大努力,以便其他人可以帮助您。没有代码,没有人知道你遇到了问题的哪个部分。你知道如何用 C 写一个for 循环吗?如何提出智能问题:catb.org/esr/faqs/smart-questions.html> 更简短、更清晰的版本:dumblittleman.com/2007/10/how-to-ask-smart-questions.html> faculty.gvc.edu/ssnyder/121/Goodquestions.html>
  • 感谢 mctylr 的链接。是的,我知道如何编写循环。实际上,我想做的是了解交换行代码的想法,然后进行适合 mt 代码的更改。

标签: c matrix row swap


【解决方案1】:

答案完全取决于你的“矩阵”是如何实现的,因为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 implementation,这可能更快,但需要一整行的临时内存。

参差不齐的数组

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

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 中实现“矩阵”的方法有很多很多,但它们大多要复杂得多,并且仅在特殊情况下才有用。当您需要它们时,您将能够根据每个问题自己回答这些问题。

【讨论】:

  • 再次感谢!我正在使用二维码。但是,当我尝试 2x3 矩阵时,出现了一些错误。第三列或列 [2] 不交换。
  • 我的意思是最后一列的行元素不交换
  • @user 注意for 循环的限制。如果您的行是 3 长,则循环应该从 0 运行到 2,通常使用 for(i=0;i&lt;3;++i) 构建。对于初学者来说,写for(i=0;i&lt;2;++i) 不会工作或for(i=0;i&lt;=2;++i) 会,但对于 c 程序员来说看起来很奇怪(非惯用)的情况并不少见。
  • 我明白了,在 for 循环中。 i
【解决方案2】:
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 使代码更具可读性。但我担心它很可能不会回答 OP,因为我怀疑它完全超出了他/她的头脑。
  • 非常感谢您的回答。我只是 C 的新手,我们还没有完成与 memcpy 的讨论
【解决方案3】:

我可能会一次交换一个元素以避免使用大量额外的存储空间。如果您主要使用矩阵通常为 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;
}

【讨论】:

    【解决方案4】:

    你的家庭作业解决了吗?

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

    【讨论】:

    • 你应该在这里添加一些讨论;更是如此,因为这是一个初学者类型的问题。这个技巧之所以有效,是因为结构的赋值语义。
    • 交换看起来不错。但是这个:row[1].m[2] = ... 糟透了。嗯,这才是重点,不是吗?
    • @Maciej #define 在这里有帮助
    • 所以这不是重点。您真的是说答案有用,而不仅仅是惩罚OP的恶作剧?我猜不到。
    【解决方案5】:

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

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

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

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

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

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

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

    【讨论】:

    • 使用 XOR 交换很少有任何收获(它通常不会更快,也不太清楚),如果ab 是同一个指针。
    【解决方案6】:
    temprow = row[1];
    row[1] = row[0];
    row[0] = temprow;
    

    【讨论】:

    • 我使用的是二维数组。请帮帮我:(
    • 使用正确的矩阵实现这可能是正确的,但作为一个简单的答案(没有讨论矩阵实现和上面的变量类型)这是非常错误的。细节很重要。
    • 如果您要交换行,无论如何都应该使用这种实现。
    • 什么是矩阵的“正确”实现?细节很重要,但正如 OP 所说,他想用 row[1] 交换 row[0]。只需将 temprow 设置为相同的类型,然后就完成了。
    • OP 还表示(最终)他使用的是普通的旧二维数组。当行类型为 double[] 或类似时,这不会工作,因为 c 不支持数组的元素复制分配语义。
    【解决方案7】:

    有一个函数叫swap

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

    【讨论】:

      猜你喜欢
      • 2019-03-24
      • 2019-07-03
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 2021-04-29
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      相关资源
      最近更新 更多