Как поменять две строки в матрице (в C)? - PullRequest
6 голосов
/ 23 августа 2010

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

1 2 3

4 5 6

7 8 9

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

4 5 6

1 2 3

7 8 9

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

Ответы [ 7 ]

18 голосов
/ 23 августа 2010

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

У рваных массивов есть два недостатка с вашей точки зрения (ну, три причины сложности управления памятью): они требуют дополнительной памяти для указателей строк, и вы не можете использовать встроенную инициализацию.

Ряд-а-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, но в большинстве случаев они намного сложнее и полезны только в специализированных ситуациях. К тому времени, когда они вам понадобятся, вы сможете сами ответить на эти вопросы в контексте каждого из них.

7 голосов
/ 23 августа 2010
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));
2 голосов
/ 23 августа 2010

решить эту домашнюю работу?

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 голосов
/ 23 августа 2010

Я бы, вероятно, поменял один элемент за раз, чтобы не использовать много дополнительной памяти.Если вы работаете в основном с такими вещами, как графические преобразования, где матрицы обычно имеют размер 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;
}
1 голос
/ 27 августа 2010

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

Вероятно, одним из наиболее элегантных подходов было бы использование функции, которая меняет местами два полученных аргумента - используя ее для обмена компонентами матрицы. Допустим, что-то вроде 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;   
} 
0 голосов
/ 26 мая 2019

Существует функция с именем swap :

#include <algorithm>
int A[][] = {{1,2,3},{4,5,6},{7,8,9}};
swap(A[0],A[2]); //swaps first and last row
0 голосов
/ 23 августа 2010
temprow = row[1];
row[1] = row[0];
row[0] = temprow;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...