使用 C 语言中的克莱姆法则求解线性方程组

CBeginner
立即练习

简介

在本实验中,你将学习如何使用克莱姆法则(Cramer's Rule)在 C 语言中求解线性方程组。本实验将引导你完成读取线性方程组的系数和常数、计算行列式,以及最终输出变量解的过程。你将创建一个 C 程序,允许用户输入系数和常数,然后程序将使用克莱姆法则提供解。本实验涵盖了基本的矩阵和线性代数概念,所学技能可应用于各种实际问题。

读取系数和常数

在这一步中,你将学习如何在 C 语言中使用克莱姆法则读取求解线性方程组所需的系数和常数。我们将创建一个程序,允许用户输入线性方程组的系数。

首先,为我们的线性方程求解器创建一个 C 源文件:

cd ~/project
nano cramer_solver.c

现在,将以下代码添加到文件中:

#include <stdio.h>

#define MAX_SIZE 3

int main() {
    float matrix[MAX_SIZE][MAX_SIZE];
    float constants[MAX_SIZE];
    int n;

    // 输入方程组的数量
    printf("输入方程的数量(最大为 3):");
    scanf("%d", &n);

    // 输入系数
    printf("输入矩阵的系数:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("输入系数 a[%d][%d]:", i + 1, j + 1);
            scanf("%f", &matrix[i][j]);
        }
    }

    // 输入常数
    printf("输入常数:\n");
    for (int i = 0; i < n; i++) {
        printf("输入常数 b[%d]:", i + 1);
        scanf("%f", &constants[i]);
    }

    // 打印输入的矩阵和常数
    printf("\n输入的矩阵:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%.2f ", matrix[i][j]);
        }
        printf("| %.2f\n", constants[i]);
    }

    return 0;
}

编译程序:

gcc -o cramer_solver cramer_solver.c

运行程序:

./cramer_solver

示例输出:

输入方程的数量(最大为3):2
输入矩阵的系数:
输入系数a[1][1]:2
输入系数a[1][2]:1
输入系数a[2][1]:-3
输入系数a[2][2]:4
输入常数:
输入常数b[1]:4
输入常数b[2]:5

输入的矩阵:
2.00 1.00 | 4.00
-3.00 4.00 | 5.00

让我们来分析一下这段代码:

  1. 我们为线性方程组定义了最大尺寸为 3x3。
  2. 程序首先要求用户输入方程的数量。
  3. 然后提示用户输入矩阵的系数。
  4. 接着要求输入线性方程的常数。
  5. 最后打印输入的矩阵和常数以供验证。

这一步通过允许用户输入线性方程组的系数和常数,为实现克莱姆法则奠定了基础。

计算行列式

在这一步中,你将学习如何在 C 语言中使用克莱姆法则计算求解线性方程组所需的行列式。我们将扩展上一个程序,使其包含行列式计算函数。

打开现有的源文件:

cd ~/project
nano cramer_solver.c

使用行列式计算函数更新代码:

#include <stdio.h>

#define MAX_SIZE 3

// 计算矩阵行列式的函数
float computeDeterminant(float matrix[MAX_SIZE][MAX_SIZE], int n) {
    if (n == 1) {
        return matrix[0][0];
    }

    if (n == 2) {
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
    }

    float det = 0;
    float submatrix[MAX_SIZE][MAX_SIZE];
    int sign = 1;

    for (int x = 0; x < n; x++) {
        int subi = 0;
        for (int i = 1; i < n; i++) {
            int subj = 0;
            for (int j = 0; j < n; j++) {
                if (j == x) continue;
                submatrix[subi][subj] = matrix[i][j];
                subj++;
            }
            subi++;
        }
        det += sign * matrix[0][x] * computeDeterminant(submatrix, n - 1);
        sign = -sign;
    }

    return det;
}

int main() {
    float matrix[MAX_SIZE][MAX_SIZE];
    float constants[MAX_SIZE];
    int n;

    // 之前的输入代码保持不变
    printf("输入方程的数量(最大为 3):");
    scanf("%d", &n);

    // 输入系数
    printf("输入矩阵的系数:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("输入系数 a[%d][%d]:", i + 1, j + 1);
            scanf("%f", &matrix[i][j]);
        }
    }

    // 输入常数
    printf("输入常数:\n");
    for (int i = 0; i < n; i++) {
        printf("输入常数 b[%d]:", i + 1);
        scanf("%f", &constants[i]);
    }

    // 计算并显示行列式
    float mainDeterminant = computeDeterminant(matrix, n);
    printf("\n主行列式:%.2f\n", mainDeterminant);

    return 0;
}

编译更新后的程序:

gcc -o cramer_solver cramer_solver.c

运行程序:

./cramer_solver

示例输出:

输入方程的数量(最大为3):2
输入矩阵的系数:
输入系数a[1][1]:2
输入系数a[1][2]:1
输入系数a[2][1]:-3
输入系数a[2][2]:4
输入常数:
输入常数b[1]:4
输入常数b[2]:5

主行列式:11.00

关于行列式计算的要点:

  1. computeDeterminant() 函数使用递归计算矩阵行列式。
  2. 它将 1x1 和 2x2 矩阵作为基础情况处理。
  3. 对于更大的矩阵,它使用余子式展开法。
  4. 该函数适用于最大为 3x3 的方阵。

这段代码演示了如何计算系数矩阵的主行列式,这是使用克莱姆法则求解线性方程组的关键步骤。

输出变量的解

在这一步中,你将通过计算并输出线性方程组中变量的解来完成克莱姆法则(Cramer's Rule)的实现。

打开现有的源文件:

cd ~/project
nano cramer_solver.c

使用克莱姆法则解的计算更新代码:

#include <stdio.h>

#define MAX_SIZE 3

// 之前的 computeDeterminant 函数保持不变
float computeDeterminant(float matrix[MAX_SIZE][MAX_SIZE], int n) {
    if (n == 1) {
        return matrix[0][0];
    }

    if (n == 2) {
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
    }

    float det = 0;
    float submatrix[MAX_SIZE][MAX_SIZE];
    int sign = 1;

    for (int x = 0; x < n; x++) {
        int subi = 0;
        for (int i = 1; i < n; i++) {
            int subj = 0;
            for (int j = 0; j < n; j++) {
                if (j == x) continue;
                submatrix[subi][subj] = matrix[i][j];
                subj++;
            }
            subi++;
        }
        det += sign * matrix[0][x] * computeDeterminant(submatrix, n - 1);
        sign = -sign;
    }

    return det;
}

// 使用克莱姆法则求解线性方程组的函数
void solveUsingCramersRule(float matrix[MAX_SIZE][MAX_SIZE], float constants[MAX_SIZE], int n) {
    float mainDeterminant = computeDeterminant(matrix, n);

    // 检查系统是否有唯一解
    if (mainDeterminant == 0) {
        printf("该系统没有唯一解(行列式为零)。\n");
        return;
    }

    // 为每个变量创建临时矩阵
    float tempMatrix[MAX_SIZE][MAX_SIZE];
    float solutions[MAX_SIZE];

    // 计算每个变量的解
    for (int i = 0; i < n; i++) {
        // 复制原始矩阵
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                tempMatrix[j][k] = matrix[j][k];
            }
        }

        // 用常数替换第 i 列
        for (int j = 0; j < n; j++) {
            tempMatrix[j][i] = constants[j];
        }

        // 计算该变量的行列式
        solutions[i] = computeDeterminant(tempMatrix, n) / mainDeterminant;
    }

    // 输出解
    printf("\n解:\n");
    for (int i = 0; i < n; i++) {
        printf("x%d = %.2f\n", i + 1, solutions[i]);
    }
}

int main() {
    float matrix[MAX_SIZE][MAX_SIZE];
    float constants[MAX_SIZE];
    int n;

    // 输入代码保持不变
    printf("输入方程的数量(最大为 3):");
    scanf("%d", &n);

    // 输入系数
    printf("输入矩阵的系数:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("输入系数 a[%d][%d]:", i + 1, j + 1);
            scanf("%f", &matrix[i][j]);
        }
    }

    // 输入常数
    printf("输入常数:\n");
    for (int i = 0; i < n; i++) {
        printf("输入常数 b[%d]:", i + 1);
        scanf("%f", &constants[i]);
    }

    // 使用克莱姆法则求解
    solveUsingCramersRule(matrix, constants, n);

    return 0;
}

编译更新后的程序:

gcc -o cramer_solver cramer_solver.c

运行程序:

./cramer_solver

示例输出:

输入方程的数量(最大为3):2
输入矩阵的系数:
输入系数a[1][1]:2
输入系数a[1][2]:1
输入系数a[2][1]:-3
输入系数a[2][2]:4
输入常数:
输入常数b[1]:4
输入常数b[2]:5

解:
x1 = 2.00
x2 = 1.00

关于解的计算的要点:

  1. solveUsingCramersRule() 函数实现了克莱姆法则。
  2. 它通过验证主行列式来检查系统是否有唯一解。
  3. 对于每个变量,它创建一个临时矩阵并计算其行列式。
  4. 通过将每个变量的行列式除以主行列式来计算解。

该程序现在使用克莱姆法则完全求解了一个线性方程组。

总结

在本实验中,你将学习如何读取线性方程组的系数和常数,这是使用 C 语言中的克莱姆法则求解方程组的第一步。该程序允许用户输入矩阵的系数和常数,然后打印输入的矩阵以供验证。这一步为后续计算行列式和输出变量的解奠定了基础。

下一步将涉及计算系数矩阵和修改后的矩阵的行列式,这是克莱姆法则的关键部分。最后一步将是通过将修改后的矩阵的行列式除以系数矩阵的行列式来输出变量的解。