RobertDeMilo

Вычисление определителя

Jul 27th, 2025
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.29 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. double det(double **matrix, int n);
  5. void input(double ***matrix, int *n, int *m);
  6. void output(double det);
  7.  
  8. int main() {
  9.     int n, m;
  10.     double **matrix = NULL;
  11.    
  12.     input(&matrix, &n, &m);
  13.    
  14.     if (n != m) {
  15.         printf("n/a\n");
  16.     } else {
  17.         double determinant = det(matrix, n);
  18.         output(determinant);
  19.     }
  20.    
  21.     // Освобождаем память
  22.     for (int i = 0; i < n; i++) {
  23.         free(matrix[i]);
  24.     }
  25.     free(matrix);
  26.    
  27.     return 0;
  28. }
  29.  
  30. // Рекурсивная функция для вычисления определителя
  31. double det(double **matrix, int n) {
  32.     double determinant = 0;
  33.    
  34.     if (n == 1) {
  35.         return matrix[0][0];
  36.     }
  37.    
  38.     double **temp = (double **)malloc((n-1) * sizeof(double *));
  39.     for (int i = 0; i < n-1; i++) {
  40.         temp[i] = (double *)malloc((n-1) * sizeof(double));
  41.     }
  42.    
  43.     int sign = 1;
  44.    
  45.     for (int k = 0; k < n; k++) {
  46.         int i_sub = 0, j_sub = 0;
  47.        
  48.         for (int i = 1; i < n; i++) {
  49.             j_sub = 0;
  50.             for (int j = 0; j < n; j++) {
  51.                 if (j == k) continue;
  52.                 temp[i_sub][j_sub] = matrix[i][j];
  53.                 j_sub++;
  54.             }
  55.             i_sub++;
  56.         }
  57.        
  58.         determinant += sign * matrix[0][k] * det(temp, n-1);
  59.         sign = -sign;
  60.     }
  61.    
  62.     for (int i = 0; i < n-1; i++) {
  63.         free(temp[i]);
  64.     }
  65.     free(temp);
  66.    
  67.     return determinant;
  68. }
  69.  
  70. void input(double ***matrix, int *n, int *m) {
  71.     scanf("%d %d", n, m);
  72.    
  73.     *matrix = (double **)malloc(*n * sizeof(double *));
  74.     for (int i = 0; i < *n; i++) {
  75.         (*matrix)[i] = (double *)malloc(*m * sizeof(double));
  76.         for (int j = 0; j < *m; j++) {
  77.             scanf("%lf", &(*matrix)[i][j]);
  78.         }
  79.     }
  80. }
  81.  
  82. void output(double det) {
  83.     printf("%.6lf\n", det);
  84. }
  85. .........................................................................................................................
  86. Код для вычисления определителя без использования рекурсии. Один из распространённых методов — это метод Гаусса с приведением матрицы к верхнетреугольному виду, после чего определитель вычисляется как произведение элементов на главной диагонали.
  87.  
  88. Код без рекурсии (метод Гаусса):
  89.  
  90. #include <stdio.h>
  91. #include <stdlib.h>
  92. #include <math.h>
  93.  
  94. double det(double **matrix, int n);
  95. void input(double ***matrix, int *n, int *m);
  96. void output(double det);
  97.  
  98. int main() {
  99.     int n, m;
  100.     double **matrix = NULL;
  101.    
  102.     input(&matrix, &n, &m);
  103.    
  104.     if (n != m) {
  105.         printf("n/a\n");
  106.     } else {
  107.         double determinant = det(matrix, n);
  108.         output(determinant);
  109.     }
  110.    
  111.     // Освобождаем память
  112.     for (int i = 0; i < n; i++) {
  113.         free(matrix[i]);
  114.     }
  115.     free(matrix);
  116.    
  117.     return 0;
  118. }
  119.  
  120. // Функция для вычисления определителя методом Гаусса (без рекурсии)
  121. double det(double **matrix, int n) {
  122.     double det = 1.0;
  123.    
  124.     for (int i = 0; i < n; i++) {
  125.         // Поиск ведущего элемента (максимального в столбце)
  126.         int max_row = i;
  127.         for (int k = i + 1; k < n; k++) {
  128.             if (fabs(matrix[k][i]) > fabs(matrix[max_row][i])) {
  129.                 max_row = k;
  130.             }
  131.         }
  132.        
  133.         // Если ведущий элемент равен нулю, определитель = 0
  134.         if (matrix[max_row][i] == 0.0) {
  135.             return 0.0;
  136.         }
  137.        
  138.         // Меняем строки местами, если нужно
  139.         if (max_row != i) {
  140.             double *temp = matrix[i];
  141.             matrix[i] = matrix[max_row];
  142.             matrix[max_row] = temp;
  143.             det *= -1; // Меняем знак определителя при перестановке строк
  144.         }
  145.        
  146.         // Приводим матрицу к верхнетреугольному виду
  147.         for (int k = i + 1; k < n; k++) {
  148.             double factor = matrix[k][i] / matrix[i][i];
  149.             for (int j = i; j < n; j++) {
  150.                 matrix[k][j] -= factor * matrix[i][j];
  151.             }
  152.         }
  153.     }
  154.    
  155.     // Вычисляем определитель как произведение диагональных элементов
  156.     for (int i = 0; i < n; i++) {
  157.         det *= matrix[i][i];
  158.     }
  159.    
  160.     return det;
  161. }
  162.  
  163. void input(double ***matrix, int *n, int *m) {
  164.     scanf("%d %d", n, m);
  165.    
  166.     *matrix = (double **)malloc(*n * sizeof(double *));
  167.     for (int i = 0; i < *n; i++) {
  168.         (*matrix)[i] = (double *)malloc(*m * sizeof(double));
  169.         for (int j = 0; j < *m; j++) {
  170.             scanf("%lf", &(*matrix)[i][j]);
  171.         }
  172.     }
  173. }
  174.  
  175. void output(double det) {
  176.     printf("%.6lf\n", det);
  177. }
  178. ....................................
  179. Входные данные
  180. 3 3
  181. 1 2 3
  182. 4 5 6
  183. 7 8 9
  184. Выходные данные
  185. 0.000000
  186. ....................................
Advertisement
Add Comment
Please, Sign In to add comment