Проблема в перестановке строк и столбцов массива

93
30 октября 2021, 05:50

Вообщем дано задание:

Допустимым преобразованием матрицы назовём перестановку двух соседних строк или двух соседних столбцов. Дана вещественная квадратная матрица порядка n (n<=12). С помощью допустимых преобразований получить матрицу, в которой максимальный элемент располагается в левом верхнем углу. Использовать функции для выполнения допустимых преобразований и для нахождения индексов максимального элемента.

Моя проблема заключается именно в том, что я не могу выполнить перестановку соседних строк или столбцов.

Вот мой код:

#include <iostream>
#include <algorithm>
using namespace std;
const int rows = 4, cols = rows;
int iMax = 0;
int jMax = 0;
int arr[rows][cols];
void arr_f()
{
    setlocale(LC_ALL, "rus");

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            cin >> arr[i][j];
        }
    }
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            cout << " " << arr[i][j] << "\t";
            if (arr[i][j] > arr[iMax][jMax])
            {
                iMax = i;
                jMax = j;
            }
        }
        cout << endl;
    }
    cout << endl << "Максимальное число массива: " << arr[iMax][jMax] << endl << endl;
}

    int main()
    {
        arr_f();
        system("pause");
    } 

Пробовал добавить функции

inline void swap_columns(const int f, const int s)
{
    for (int i = 0; i < rows; ++i)
    {
        swap(arr[i][f], arr[i][s]);
    }
}
inline void swap_rows(const int f, const int s)
{
    for (int i = 0; i < rows; ++i)
    {
        swap(arr[f][i], arr[s][i]);
    }
}

и добавить следующее в функцию arr_f():

swap_rows(0, iMax);
    swap_columns(0, jMax);
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            cout << " " << arr[i][j] << "\t";
        }
        cout << endl;
    }

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

Answer 1

Все просто, давайте представим матрицу как указатель на указатель(для простоты), тогда мы можем ее инициализировать так(грязный код с new и delete для большего понимания). сам swap выполняется просто (просто заменим один указатель на другой)

Для начала создадим сам массив

int** InitArrayint(int size_x, int size_y)
{
    int** arr = new int*[size_x];
    if (arr == nullptr) {
        return nullptr;
    }
    for (int i{0}; i < size_x; ++i) {
        arr[i] = new int[size_y];
        if (arr[i] == nullptr) {
            return nullptr;
        }
    }
    int k{0};
    for(int i{0}; i < size_x; ++i) {
        for (int j{0}; j < size_y; ++j) {
            arr[i][j] = k;
            ++k;
        }
    }
    return arr;
}

и не забудем почистить за собой

int DeinitArray(int** arr, int size_x)
{
    if (arr == nullptr) {
        return -1;
    }
    for (int i{0}; i < size_x; ++i) {
        if (arr[i] == nullptr) {
            std::cerr << "Error deinit colunm " << i << std::endl;
            continue;
        }
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}

тут я думаю все понятно в массив указателей аллоцируем еще один массив указателей.

Теперь самое простое - поменять строки местами (просто переставим указатели на строки через tmp - временную строку)

int ChanheString(int** arr, int size_x, int n_1, int n_2)
{
    if (n_1 >= size_x || n_2 >= size_x) {
        return -1;
    }
    int* tmp = arr[n_1];
    arr[n_1] = arr[n_2];
    arr[n_2] = tmp;
    return 0;
}

Далее 2-а часть задачи (смена столбцов) - тут придется сохранять временную строку для этого воспользуемся циклом и поменяем все местами.

int ChangeColumn(int** arr, int size_x, int size_y, int n_1, int n_2)
{
    if (n_1 >= size_y ||  n_2 >= size_y) {
        return -1;
    }
    int* tmp_arr = new int[size_y];
    for (int i{0}; i < size_x; ++i) {
        tmp_arr[i] = arr[i][n_1];
    }
    for (int i{0}; i < size_x; ++i) {
        arr[i][n_1] = arr[i][n_2];
    }
    for (int i{0}; i < size_x; ++i) {
        arr[i][n_2] = tmp_arr[i];
    }
    delete[] tmp_arr;
    return 0;
}

Далее мелкая функция все вывести в stdout

void PrintArr(int** arr, int size_x, int size_y)
{
    for(int i{0}; i < size_x; ++i) {
        for (int j{0}; j < size_y; ++j) {
            std::cout << arr[i][j] << "\t";
        }
        std::cout << "\n";
    }
    std::cout << "\n";
}

Ну и дергаем все в main

int main()
{
    int ret{0};
    int size_x{3};
    int size_y{4};
    auto arr = InitArrayint(size_x, size_y);
    PrintArr(arr, size_x, size_y);
    ret = ChanheString(arr, size_x, 0 ,1);
    if (ret != 0) {
        std::cout << "Error" << std::endl;
    }
    PrintArr(arr, size_x, size_y);
    ret = ChangeColumn(arr, size_x, size_y, 1 ,2);
    if (ret != 0) {
        std::cout << "Error" << std::endl;
    }
    PrintArr(arr, size_x, size_y);
    ret = DeinitArray(arr, size_x);
    if (ret != 0) {
        std::cout << "Error" << std::endl;
    }
    return 0;
}
READ ALSO
Книги и учебные ресурсы по фундаментальным знаниям и навыкам разработчика

Книги и учебные ресурсы по фундаментальным знаниям и навыкам разработчика

Рекомендуемая литература и документация по знаниям и навыкам разработки, не привязанным к конкретным языкам и платформам

157
SFML, View и отрисовка

SFML, View и отрисовка

Подскажите, пожалуйста, отрисовывает ли SFML то, что находится за пределами используемого вида?

81
Свой тип данных с границами в C++

Свой тип данных с границами в C++

Мне нужно создать тип данных Percent, который бы хранил в себе только целые числа от 0 до 100, и чтобы логика была такая:

103
При клике на ссылку закрытие меню (jquery)

При клике на ссылку закрытие меню (jquery)

У меня есть меню для мобильной версии; я не силен в js и jqueryЯ не понимаю, как сделать так, что бы при нажатии на ссылку меню закрывалось

111