C++ 代码实现定义法计算行列式的值

2023-11-20

一、前言

         最近在捣鼓C++,学到线代的行列式之后就想着来捣鼓一下求行列式的值。主要原因是当时群里有人在捣鼓着用上下三角来求值,所以我最后就去玩定义法求值了。

二、n阶行列式的定义

         从定义中我们可以看出值计算公式由三个部分组成:分别是逆序数r,行列式中n项的相乘并相加,以及全排列 j1 、j2 、j3......jn。

 三、代码实现

 1.首先我们先构架好基本框架:

#include <iostream>
#include <cmath>
using namespace std;

const int u = 10;            //最大阶数限制

int main() 
{

    int finalanswer;
    int arr[u][u];

    cout << "请输入行列式的阶数" << endl;
    cin >> n;

    for (int i = 0; i < n; i++)                           //给行列式的每项进行赋值 
    {
        cout << endl;
        for (int h = 0; h < n; h++)
        {
            cout << "a" << i + 1 << h + 1 << " 的值:";
            cin >> arr[i][h];
        }
    }

}

        cmath的头文件是因为接下来的逆序数需要用到pow(或者你也可以用for循环?)

2.排列数

int a[u];        //需要进行排列的数的数组

for (i = 0; i < n; i++)         //给排列赋值
{
     a[i] = i + 1;
}

          定义中的j1,j2,jn就是排列数,通过排列数来最后得出所需要相加的所有的项的值。

3.逆序数

int Reverse(int n, int a[])                 //逆序数
{
    int t = 0;
    for (int i = 1; i < n; i++)
    {
        for (int h = 0; h < i; h++)
        {
            if (a[i]<a[h])
            {
                t = t + 1;
            }
        }
    }
    return t;
}

        逆序数的算法比较简单,只需要用两层for检测某一位的数的前几位有多少数比他大即可。

4.求全排列

void Perm(int start, int end, int a[])        start=0  end为行列式阶数
{

    if (start == end)
    {
        for (int j = 0; j < end; j++)
        {
            cout << a[j] << " ";
        }
        cout << endl;
    }
    for (int i = start; i < end; i++)
    {
        swap(a[start], a[i]);

        Perm(start + 1, end, a);

        swap(a[i], a[start]);
    }
}

        这是用递归法求全排列的一种方法,参考了这位大哥的方法:          https://blog.csdn.net/hf19931101/article/details/79452799

        其中start = 0,end就是行列式的阶数,也就是n。具体的解析可以看上面链接的。 

5.计算行列式每个项的值

        行列式最终的值是由几个项相加而成的,而那几个项则是由n个行列式中的元素相乘而得来的,而项中每项元素的列(行)下标则是1 2 3 ... n的某一种排列,而所有的项的列(行)下标就构成了1 2 3 ... n 的所有排列情况。

int Answer(int arr[u][u], int a[], int n, int t)              //计算行列式的每项的值
{
    int answer = 0;
    int temp_answer = 1;
    int t_2 = 0;

    for (int i = 0; i < n; i++)
    {
        temp_answer = temp_answer * arr[i][a[i]-1];
    }

    t_2 = pow(-1, t);

    answer = temp_answer * t_2;

    return answer;
}

        t 就是该项的各个元素的列(行)下标所对应的逆序数。temp_answer是该项中元素的累乘。t_2则是 - 1 的t次方。

6.所有项相加得出最终结果

        我们定义一个Final_Answer来作为最终结果,并且将Answer函数和Perm函数以及Reverse相融合。

void Perm(int start, int end, int a[], int arr[10][10], int &Final_Answer)                
{

    if (start == end)
    {
        Final_Answer = Final_Answer + Answer(arr, a, end, Reverse(end, a));
        return;
    }
    for (int i = start; i < end; i++)
    {
        swap(a[start], a[i]);      
        Perm(start + 1, end, a, arr, Final_Answer);  
        swap(a[i], a[start]);      
    }

}

        Final_Answer的值是一个值传递,因此我们用&来进行引用(或者利用指针)。Reverse函数所在的位置就是Answer函数的 t ,也就是逆序数。最后再在main函数之中调用并cout一下即可。

    Perm(0, n, a, arr, Final_Answer);

    cout << "行列式的值为: " << Final_Answer << endl;

7.全部代码

#include <iostream>
#include <cmath>
using namespace std;


int Reverse(int n, int a[])                 
{
    int t = 0;
    for (int i = 1; i < n; i++)
    {
        for (int h = 0; h < i; h++)
        {
            if (a[i]<a[h])
            {
                t = t + 1;
            }
        }
    }

    return t;
}

int Answer(int arr[10][10], int a[], int n, int t)              
{
    int answer = 0;
    int temp_answer = 1;
    int t_2 = 0;

    for (int i = 0; i < n; i++)
    {
        temp_answer = temp_answer * arr[i][a[i]-1];
    }

    t_2 = pow(-1, t);

    answer = temp_answer * t_2;

    return answer;
}

void Perm(int start, int end, int a[], int arr[10][10], int &Final_Answer)                
{

    if (start == end)
    {
        Final_Answer = Final_Answer + Answer(arr, a, end, Reverse(end, a));
        return;
    }
    for (int i = start; i < end; i++)
    {
        swap(a[start], a[i]);      
        Perm(start + 1, end, a, arr, Final_Answer);   
        swap(a[i], a[start]);      
    }

}


int main() 
{
    int Final_Answer = 0;
    int i, n, a[10];
    int arr[10][10];
    cout << "请输入行列式的阶数" << endl;
    cin >> n;
    for (i = 0; i < n; i++)         //给排列赋值
    {
        a[i] = i + 1;
    }

    for (int i = 0; i < n; i++)
    {
        cout << endl;
        for (int h = 0; h < n; h++)
        {
            cout << "a" << i + 1 << h + 1 << " 的值:";
            cin >> arr[i][h];
        }
    }

    Perm(0, n, a, arr, Final_Answer);

    cout << "行列式的值为: " << Final_Answer << endl;

    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 代码实现定义法计算行列式的值 的相关文章

随机推荐

  • 用vue写一个学校官网

    首先 你需要准备一个文本编辑器 如 Sublime Text VSCode 等 和浏览器 然后 你需要安装 Vue 你可以通过使用 npm 命令来安装 npminstall g vue
  • Ubuntu Server 22.04 安装桌面

    Ubuntu Server 22 04 安装桌面 sudo apt get update sudo apt get upgrade apt get install y ubuntu desktop 如果你不想安装一些附加的程序 可用以下命令
  • Tomcat startup.bat Using CATALINA_OPTS: ““,启动闪退

    Tomcat 控制台打开startup bat 发现Tomcat终端窗口闪退打不开 在startup bat最后加一个pause 会弹出Using CATALINA OPTS 重新设置了JAVA HOME 没用 在startup bat最前
  • python对csv文档进行读,写,追加操作(csv,pandas)

    python处理csv文档的两种方法 csv pandas python处理csv一般采用两种方法一种是import pandas 另一种是 import csv 本文将介绍这两种方法对csv进行读 写 追加的操作 1 import pan
  • mysql unique key使用_mysql unique key在查询中的使用与相关问题

    1 建表语句 CREATE TABLE employees emp no int 11 NOT NULL birth date date NOT NULL first name varchar 14 NOT NULL last name v
  • WordPress多站点伪静态的设置方式(WP站群必备)

    apache的设置方式 正常参考wordpress自带的设置方式即可 本文只介绍Ngnix及IIS下Wordpress多站点伪静态设置方式 Ngnix的wordpress多站点伪静态设置方式 wordpress固定链接设置 try file
  • Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:快速入门

    文章目录 目的 特征 安装 快速体验 注意事项 总结 目的 Arduino for ESP8266 和 Arduino for ESP32 中默认就有WebServer 不过这些WebServer都是同步的 不支持同时处理多个连接 这在很多
  • AngularJs单元测试

    这篇文章主要介绍了angularJS中的单元测试实例 本文主要介绍利用Karma和Jasmine来进行ng模块的单元测试 并用Istanbul 来生成代码覆盖率测试报告 需要的朋友们可以参考下 以下可全都是干货哦 当ng项目越来越大的时候
  • 如何在Insert插入操作之后,获取自增主键的ID值

    背景说明 MyBatis中 在大多数情况下 我们向数据库中插入一条数据之后 并不需要关注这条新插入数据的主键ID 我们也知道 正常在DAO中的插入语句虽然可以返回一个int类型的值 但是这个值表示的是插入影响的行数 而不是新插入数据的主键I
  • Unity3D如何修改Button显示的文字以及深入了解Button组件

    在创建了一个Button后 结构如图 先仔细观察一下Button的Inspector视图 发现其中竟然有一个叫Button的脚本组件 新建脚本 代码如下 并将该脚本绑定给Canvas组件 using UnityEngine UI using
  • winform记录

    SpeechSynthesizer 下边代码多次调用 会导致内存溢出outofmemory SpeechSynthesizer 需要改为全局静态 private void button Click object sender EventAr
  • 【MySQL笔记】MySQL8新特性 — 计算列

    什么叫计算列呢 简单来说就是某一列的值是通过别的列计算得来的 例如 a 列值为 1 b 列值为 2 c 列不需要手动插入 定义 a b 的结果为 c 的值 那么 c 就是计算列 是通过别的列计算得来的 在 MySQL 8 中 CREATE
  • Pytorch Torch.utils.data.Sampler

    对于 可迭代样式的数据集 数据加载顺序完全由用户定义的可迭代样式控制 这样可以更轻松地实现块读取和动态批处理大小 例如 通过每次生成一个批处理的样本 为了从数据集中读取数据 pytorch提供了Sampler基类与多个子类实现不同方式的数据
  • 天刀服务器维护4月19,5月19日服务器例行维护公告

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 亲爱的玩家 青龙乱舞区 大地飞鹰区 沧海云帆区 把酒邀月区全部服务器将在5月19日6 00 10 00停机维护更新 维护完成后上述各服务器客户端版本更新至2 1 47 18 由于机房网络波动 云
  • 【数字IC】从零开始的Verilog SPI设计

    从零开始的Verilog SPI协议设计 一 写在前面 1 1 协议标准 1 2 数字IC组件代码 1 3 设计要求 1 4 其他协议解读 1 4 1 UART协议 1 4 2 SPI协议 1 4 3 I2C协议 1 4 4 AXI协议 二
  • BLIP论文笔记

    BLIP Bootstrapping Language Image Pre training for Unified Vision Language Understanding and Generation Abstract 1 Intro
  • 在封装或使用el-dialog的时候无法获取到 $refs的坑

    经常使用 vue 的对element ui都不陌生 他的el dialog弹框组件为了性能的提升 第一次打开之前是不会渲染body内容的 这样子将会导致一个问题 我们无法获取到 dom 解决方法 方法一 因为源码是通过rendered 参数
  • 2021全国电设(F题)openmv的图像识别之数字识别

    基于openmv的图像识别 通过参加全国电子设计大赛F题总结出openmv4的数字识别 其它版本暂时没试过 欢迎交流 openmv简介 OpenMV是一个开源 低成本 功能强大的机器视觉模块 以STM32F427CPU为核心 集成了OV77
  • py214-基于Python+django的网购平台购物商城

    开发语言 Python python框架 django 软件版本 python3 7 python3 8 数据库 mysql 5 7或更高版本 数据库工具 Navicat11 开发软件 PyCharm vs code 前端框架 vue js
  • C++ 代码实现定义法计算行列式的值

    一 前言 最近在捣鼓C 学到线代的行列式之后就想着来捣鼓一下求行列式的值 主要原因是当时群里有人在捣鼓着用上下三角来求值 所以我最后就去玩定义法求值了 二 n阶行列式的定义 从定义中我们可以看出值计算公式由三个部分组成 分别是逆序数r 行列