Вычисление определителя матрицы на языке C

CCBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом лабораторном занятии (LabEx) вы научитесь вычислять определитель квадратной матрицы на языке программирования C. В рамках лабораторной работы рассматриваются следующие этапы: чтение размерности и элементов матрицы, использование рекурсивного метода или метода LU-разложения для вычисления определителя и вывод конечного результата. Пошаговые инструкции помогут вам создать программу, которая может обрабатывать квадратные матрицы размером до 10x10, позволяя динамически вводить элементы матрицы и отображать вычисленный определитель.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("C")) -.-> c/UserInteractionGroup(["User Interaction"]) c(("C")) -.-> c/ControlFlowGroup(["Control Flow"]) c(("C")) -.-> c/CompoundTypesGroup(["Compound Types"]) c(("C")) -.-> c/FunctionsGroup(["Functions"]) c/ControlFlowGroup -.-> c/for_loop("For Loop") c/CompoundTypesGroup -.-> c/arrays("Arrays") c/FunctionsGroup -.-> c/recursion("Recursion") c/UserInteractionGroup -.-> c/user_input("User Input") c/UserInteractionGroup -.-> c/output("Output") subgraph Lab Skills c/for_loop -.-> lab-435157{{"Вычисление определителя матрицы на языке C"}} c/arrays -.-> lab-435157{{"Вычисление определителя матрицы на языке C"}} c/recursion -.-> lab-435157{{"Вычисление определителя матрицы на языке C"}} c/user_input -.-> lab-435157{{"Вычисление определителя матрицы на языке C"}} c/output -.-> lab-435157{{"Вычисление определителя матрицы на языке C"}} end

Чтение размерности и элементов (квадратная матрица)

На этом этапе вы научитесь считывать размерность и элементы квадратной матрицы на языке программирования C. Мы создадим программу, которая позволит пользователям динамически вводить размер матрицы и ее элементы.

Сначала создадим новый файл на языке C для нашей программы вычисления определителя матрицы:

cd ~/project
nano matrix_determinant.c

Теперь добавьте следующий код для чтения размерности и элементов матрицы:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 10

int main() {
    int n, i, j;
    int matrix[MAX_SIZE][MAX_SIZE];

    // Чтение размерности матрицы
    printf("Введите размер квадратной матрицы (1-%d): ", MAX_SIZE);
    scanf("%d", &n);

    // Проверка корректности размера матрицы
    if (n < 1 || n > MAX_SIZE) {
        printf("Некорректный размер матрицы. Пожалуйста, введите размер от 1 до %d.\n", MAX_SIZE);
        return 1;
    }

    // Чтение элементов матрицы
    printf("Введите элементы матрицы:\n");
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }

    // Вывод матрицы для проверки ввода
    printf("\nВведенная матрица:\n");
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Скомпилируйте и запустите программу:

gcc matrix_determinant.c -o matrix_determinant
./matrix_determinant

Пример вывода:

Введите размер квадратной матрицы (1-10): 3
Введите элементы матрицы:
Введите элемент [0][0]: 1
Введите элемент [0][1]: 2
Введите элемент [0][2]: 3
Введите элемент [1][0]: 4
Введите элемент [1][1]: 5
Введите элемент [1][2]: 6
Введите элемент [2][0]: 7
Введите элемент [2][1]: 8
Введите элемент [2][2]: 9

Введенная матрица:
1 2 3
4 5 6
7 8 9

Разберем код по частям:

  • Мы определяем максимальный размер матрицы равным 10, чтобы избежать избыточного выделения памяти.
  • Программа сначала запрашивает у пользователя размер матрицы.
  • Затем она проверяет введенное значение, чтобы убедиться, что оно находится в допустимом диапазоне.
  • После этого программа предлагает пользователю ввести каждый элемент матрицы по отдельности.
  • В конце программа выводит введенную матрицу для проверки ввода.

Использование рекурсивного метода или метода LU-разложения

На этом этапе мы реализуем рекурсивный метод для вычисления определителя матрицы. Мы модифицируем предыдущую программу, добавив функцию для вычисления определителя.

Обновите файл matrix_determinant.c:

nano matrix_determinant.c

Замените предыдущее содержимое следующим кодом:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 10

// Функция для рекурсивного вычисления определителя
int determinant(int matrix[MAX_SIZE][MAX_SIZE], int n) {
    int det = 0;
    int submatrix[MAX_SIZE][MAX_SIZE];

    // Базовый случай для матрицы 1x1
    if (n == 1) {
        return matrix[0][0];
    }

    // Базовый случай для матрицы 2x2
    if (n == 2) {
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
    }

    // Рекурсивный случай для больших матриц
    int sign = 1;
    for (int k = 0; k < n; k++) {
        // Создание подматрицы
        int subi = 0;
        for (int i = 1; i < n; i++) {
            int subj = 0;
            for (int j = 0; j < n; j++) {
                if (j == k) continue;
                submatrix[subi][subj] = matrix[i][j];
                subj++;
            }
            subi++;
        }

        // Рекурсивное вычисление
        det += sign * matrix[0][k] * determinant(submatrix, n - 1);
        sign = -sign;
    }

    return det;
}

int main() {
    int n, i, j;
    int matrix[MAX_SIZE][MAX_SIZE];

    // Чтение размерности матрицы
    printf("Введите размер квадратной матрицы (1-%d): ", MAX_SIZE);
    scanf("%d", &n);

    // Проверка корректности размера матрицы
    if (n < 1 || n > MAX_SIZE) {
        printf("Некорректный размер матрицы. Пожалуйста, введите размер от 1 до %d.\n", MAX_SIZE);
        return 1;
    }

    // Чтение элементов матрицы
    printf("Введите элементы матрицы:\n");
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }

    // Вычисление и вывод определителя
    int det = determinant(matrix, n);
    printf("\nОпределитель матрицы: %d\n", det);

    return 0;
}

Скомпилируйте и запустите программу:

gcc matrix_determinant.c -o matrix_determinant
./matrix_determinant

Пример вывода:

Введите размер квадратной матрицы (1-10): 3
Введите элементы матрицы:
Введите элемент [0][0]: 1
Введите элемент [0][1]: 2
Введите элемент [0][2]: 3
Введите элемент [1][0]: 4
Введите элемент [1][1]: 5
Введите элемент [1][2]: 6
Введите элемент [2][0]: 7
Введите элемент [2][1]: 8
Введите элемент [2][2]: 9

Определитель матрицы: 0

Основные моменты рекурсивного вычисления определителя:

  • Функция determinant() использует рекурсивный подход для вычисления определителя матрицы.
  • Для матриц 1x1 и 2x2 есть базовые случаи с прямым вычислением.
  • Для больших матриц используется метод разложения по первой строке с помощью алгебраических дополнений.
  • Функция создает подматрицы и рекурсивно вычисляет их определители.

Вывод определителя

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

Обновите файл matrix_determinant.c:

nano matrix_determinant.c

Замените предыдущее содержимое следующим улучшенным кодом:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_SIZE 10

// Функция для рекурсивного вычисления определителя
int determinant(int matrix[MAX_SIZE][MAX_SIZE], int n) {
    int det = 0;
    int submatrix[MAX_SIZE][MAX_SIZE];

    // Базовый случай для матрицы 1x1
    if (n == 1) {
        return matrix[0][0];
    }

    // Базовый случай для матрицы 2x2
    if (n == 2) {
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
    }

    // Рекурсивный случай для больших матриц
    int sign = 1;
    for (int k = 0; k < n; k++) {
        // Создание подматрицы
        int subi = 0;
        for (int i = 1; i < n; i++) {
            int subj = 0;
            for (int j = 0; j < n; j++) {
                if (j == k) continue;
                submatrix[subi][subj] = matrix[i][j];
                subj++;
            }
            subi++;
        }

        // Рекурсивное вычисление
        det += sign * matrix[0][k] * determinant(submatrix, n - 1);
        sign = -sign;
    }

    return det;
}

// Функция для вывода матрицы с форматированием
void print_matrix(int matrix[MAX_SIZE][MAX_SIZE], int n) {
    printf("\nMatrix:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%5d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int n, i, j;
    int matrix[MAX_SIZE][MAX_SIZE];
    bool valid_input = false;

    while (!valid_input) {
        // Чтение размерности матрицы
        printf("Введите размер квадратной матрицы (1-%d): ", MAX_SIZE);
        if (scanf("%d", &n)!= 1) {
            printf("Некорректный ввод. Пожалуйста, введите число.\n");
            while (getchar()!= '\n'); // Очистка буфера ввода
            continue;
        }

        // Проверка корректности размера матрицы
        if (n < 1 || n > MAX_SIZE) {
            printf("Некорректный размер матрицы. Пожалуйста, введите размер от 1 до %d.\n", MAX_SIZE);
            continue;
        }

        valid_input = true;
    }

    // Чтение элементов матрицы
    printf("Введите элементы матрицы:\n");
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            while (scanf("%d", &matrix[i][j])!= 1) {
                printf("Некорректный ввод. Пожалуйста, введите целое число для элемента [%d][%d]: ", i, j);
                while (getchar()!= '\n'); // Очистка буфера ввода
            }
        }
    }

    // Вывод введенной матрицы
    print_matrix(matrix, n);

    // Вычисление и вывод определителя
    int det = determinant(matrix, n);

    // Форматированный вывод определителя
    printf("\n--- Determinant Calculation ---\n");
    printf("Matrix Dimension: %d x %d\n", n, n);
    printf("Determinant: %d\n", det);

    return 0;
}

Скомпилируйте и запустите программу:

gcc matrix_determinant.c -o matrix_determinant
./matrix_determinant

Пример вывода:

Введите размер квадратной матрицы (1-10): 3
Введите элементы матрицы:
Введите элемент [0][0]: 1
Введите элемент [0][1]: 2
Введите элемент [0][2]: 3
Введите элемент [1][0]: 4
Введите элемент [1][1]: 5
Введите элемент [1][2]: 6
Введите элемент [2][0]: 7
Введите элемент [2][1]: 8
Введите элемент [2][2]: 9

Matrix:
    1     2     3
    4     5     6
    7     8     9

--- Determinant Calculation ---
Matrix Dimension: 3 x 3
Determinant: 0

Основные улучшения:

  • Добавлена валидация ввода для обработки некорректных данных
  • Создана отдельная функция для вывода матрицы с лучшим форматированием
  • Улучшен вывод для ясного отображения размерности матрицы и определителя
  • Улучшена обработка ошибок при вводе пользователем

Резюме

В этом лабораторном занятии (LabEx) вы научились считывать размерность и элементы квадратной матрицы на языке программирования C. Вы создали программу, которая позволяет пользователям динамически вводить размер матрицы и ее элементы. Программа проверяет корректность размера матрицы, а затем запрашивает у пользователя ввод элементов матрицы. В конце программа выводит введенную матрицу для проверки ввода.

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