Как поменять две строки в матрице (в C)?

, например, с учетом матрицы:

1 2 3

4 5 6

7 8 9

если вы собираетесь поменять местами строку [0] и строку [1], результирующая матрица будет:

4 5 6

1 2 3

7 8 9

Можете ли вы, ребята, помочь мне получить код на C для этого?

6
задан dmckee 23 August 2010 в 18:55
поделиться

6 ответов

Ответ полностью зависит от того, как реализована ваша "матрица", потому что в языке 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;
}

(здесь r1 и r2 — это целые числа, которые были установлены для двух строк, которые вы хотите поменять местами) или см. реализацию Джеймса 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];

Others

Есть много, много других способов реализовать "матрицу" в c, но они в основном намного сложнее и полезно только в особых случаях. К тому времени, когда они вам понадобятся, вы сможете ответить на эти вопросы для себя в контексте каждого из них.

18
ответ дан 8 December 2019 в 03:08
поделиться
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));
7
ответ дан 8 December 2019 в 03:08
поделиться

решить эту проблему твое домашнее задание?

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;
}
2
ответ дан 8 December 2019 в 03:08
поделиться

Я бы, вероятно, менял по одному элементу за раз, чтобы избежать использования большого количества дополнительной памяти. Если вы работаете в основном с такими вещами, как графические преобразования, где матрицы обычно 3x3 или 4x4, подход Джеймса Куррана вероятно немного лучше. Если вы работаете (или можете работать) с действительно большими матрицами, это сэкономит память и, вполне возможно, будет работать быстрее:

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;
}
2
ответ дан 8 December 2019 в 03:08
поделиться
temprow = row[1];
row[1] = row[0];
row[0] = temprow;
0
ответ дан 8 December 2019 в 03:08
поделиться

Эй! это мой первый пост о переполнении стека, я знаю, что он довольно длинный, надеюсь, меня не забанят!

Возможно, одним из самых элегантных подходов было бы использование функции, которая меняет местами два полученных аргумента — использование ее для замены компонентов матрицы. Скажем что-то вроде swap(a,b). Как многие уже говорили, нам следует подумать об использовании вспомогательной переменной

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

Недавно я подобрался к новому методу, который показался мне впечатляющим, с использованием побитовой операции XOR (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;   
} 
1
ответ дан 8 December 2019 в 03:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: