你如何在矩阵中交换两行(在C中)?

例如,给定一个矩阵:

1 2 3

4 5 6

7 8 9

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

4 5 6

1 2 3

7 8 9

你们能帮助我在C中获取代码吗?

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

你在使用二维数组吗?

 double m[3][3]; 

或者是其他东西?

二维数组

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

 for (i=0; i 

(这里r1r2是已经设置为你要交换的两行的整数)或者看到James的memcpy实现可能更快但需要整行的临时记忆。

衣衫褴褛的arrays

如果此操作非常常见且分析显示它耗费了大量时间,则可以考虑使用矩阵的不规则数组实现。 像这样的东西:

 double **m; m = malloc(sizeof(double*)*NUMROWS); /* put error checking here */ for (i=0; i 

关于此结构的有趣部分是您仍然可以使用[][]表示法访问它,但行交换操作变为

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

从你的观点来看,粗糙的数组有两个缺点(三,导致内存管理麻烦的原因):它们需要为行指针提供额外的存储空间,而且你不能使用内联初始化。

行AS-astructure

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中实现“矩阵”有许多其他方法,但它们通常更复杂,仅在特殊情况下有用。 当你需要它们时,你将能够在每个问题的背景下为自己回答这些问题。

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

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

解决这个你的功课?

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

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

可能最优雅的方法之一是使用交换两个接收参数的函数 – 使用它来交换矩阵组件。 让我们说像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; } 
 temprow = row[1]; row[1] = row[0]; row[0] = temprow;