首页 > 其他分享 >基于C语言实现整数行列式

基于C语言实现整数行列式

时间:2024-03-17 18:00:43浏览次数:29  
标签:int 整数 C语言 ++ 行列式 printf fac arrange

在本文章内,将会实现行列式的建立、销毁、打印、计算四个操作。

鉴于笔者技术有限,此行列式只针对整数int型,请读者自行扩充~_~。

1.行列式的建立与销毁

我们首先建立行列式的数据类型,由于行列式规模的不确定,采用动态分配方法。

typedef struct
{
	int n;
	int* p;
}determinant;

建立函数

void build_deter(determinant *d)//创建行列式
{
	printf("请输入行列数:>");//输入行列式
	scanf("%d", &d->n);

	d->p = (int*)malloc(sizeof (int)* d->n*d->n);//为行列式分配空间
	if (d->p == NULL)
	{
		printf("%s", strerror(errno));
	}

	printf("请按行输入值:>");
	for (int i = 0; i < d->n; i++)
	{
		for (int j = 0; j < d->n; j++)
		{
			scanf("%d",(d->p)+(i*d->n+j));
		}
	}
	printf("building over!\n");
}

销毁函数

void free_deter(determinant* d)//释放空间
{
	free(d->p);
	d->p = NULL;
}

2.行列式的打印

void dis_deter(determinant d)//打印行列式
{
	for (int i = 0; i < d.n; i++)
	{
		printf("|");
		for (int j = 0; j < d.n; j++)
		{
			printf("%-3d ", *((d.p) + (i * d.n + j)));
		}
		printf("|\n");
	}
	printf("printing over!\n");
}

其中由于动态分配原因,采用*((d.p) + (i * d.n + j))来模拟二维的定位。

3.行列式的计算

贴一张行列式的计算公式

可以看出,我们只需要解决两个问题,一个是找出p1p2p3……pn的全排列,并以此找到一组a进行相加,另一个是找到p1p2p3……pn的逆序数,从而确定每一组a前面的符号。

对于全排列,我在上一文章有讲实现原理,在此不加赘述,想要了解可以自行传送~_~,https://blog.csdn.net/2301_79847688/article/details/136762462

贴个代码:

int fac(int n)//计算阶乘
{
	int result=1;
	for (int i = n; i > 0; i--)
	{
		result *= i;
	}
	return result;
}

void change(int* a, int* b)//交换函数
{
	int c;
	c = *b;
	*b = *a;
	*a = c;
}

void bubble_sort(int* arrange,int n)//排序
{
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - 1 - i; j++)
		{
			if (arrange[j] > arrange[j + 1])
				change(arrange+j, arrange+j+1);
		}
	}
}

void tran_arrange(int* arrange, int j, int n)//改变排列
{
	if (j == 0)//自然顺序做首项
	{
		return;
	}
	if (n == 2)
	{
		change(arrange, arrange + 1);
	}
	else if(n == 3)//等于3做奇偶不同的对换
	{
		if (j % 2 == 0)
		{
			change(arrange, arrange + 1);
		}
		else if (j % 2 == 1)
		{
			change(arrange + 1, arrange + 2);
		}
	}
	else //大于3递归
	{
		if (j % fac(n - 1) == 0)//在后面数循环结束后,调换首数和后面一个数,产生新的组合
		{
			int tmp = j;
			if (tmp > fac(n))
				tmp = tmp % fac(n);//tmp要在fac(n)内,防止(1)越界

			bubble_sort(arrange + 1,n-1);//排序方便调换
			if (tmp == 0)//自然顺序做首排列,第0次
			{
				return;
			}
			if (tmp == fac(n - 1))
				change(arrange, arrange + n - 1);//调换算法,第一次换最后一位
			else
				change(arrange, arrange + n - (tmp / fac(n - 1)) + 1);//(1)之后“/”
		}
		tran_arrange(arrange+1,j,n-1);
	}
}

对于逆序数,对于排列中一个元素,他后面有多少比他小的数,那他就构成了多少逆序数,而排列的总逆序数,就是所有元素对应逆序数的和。

大体思想是这样,看看代码:

int count_re(int* arrange,int n)//统计逆序数
{
	int count = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = i+1; j < n; j++)
		{
			if (arrange[i] > arrange[j])
				count++;
		}
	}
	if (count % 2 == 1)
		return -1;
	else
		return 1;
}

这样我们就解决了所有算法问题,只需要用循环得到每一个数再相加就可以了,看看代码:

int count_deter(determinant d)//计算行列式
{
	int result = 0;//行列式最终结果
	int one = 1;//行列式的每个积
	int *col_arrange = (int*)malloc(sizeof(int)*d.n);//创建一个记录列排列的数组
	if (col_arrange == NULL)
	{
		printf("%s", strerror(errno));
	}

	for (int i = 0; i < d.n; i++)
	{
		*(col_arrange+i) = i;
	}//赋值

	for (int r = 0; r < fac(d.n); r++)//所有行列式的结果
	{
		one = 1;
		tran_arrange(col_arrange,r,d.n);//确定一个列的排序
		for (int i = 0; i < d.n; i++)
		{
			int a = *(d.p+(i*d.n)+col_arrange[i]);//行列式每个数
			one = a*one;
		}
		result += one* count_re(col_arrange, d.n);
	}

	free(col_arrange);
	col_arrange = NULL;
	return result;
}

4.总结

这便是所有内容,感谢观看~_~,贴个代码: 

#define _CRT_SECURE_NO_WARNINGS

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

typedef struct
{
	int n;
	int* p;
}determinant;

int fac(int n)//计算阶乘
{
	int result=1;
	for (int i = n; i > 0; i--)
	{
		result *= i;
	}
	return result;
}

void change(int* a, int* b)//交换函数
{
	int c;
	c = *b;
	*b = *a;
	*a = c;
}

void bubble_sort(int* arrange,int n)//排序
{
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - 1 - i; j++)
		{
			if (arrange[j] > arrange[j + 1])
				change(arrange+j, arrange+j+1);
		}
	}
}

void tran_arrange(int* arrange, int j, int n)//改变排列
{
	if (j == 0)//自然顺序做首项
	{
		return;
	}
	if (n == 2)
	{
		change(arrange, arrange + 1);
	}
	else if(n == 3)//等于3做奇偶不同的对换
	{
		if (j % 2 == 0)
		{
			change(arrange, arrange + 1);
		}
		else if (j % 2 == 1)
		{
			change(arrange + 1, arrange + 2);
		}
	}
	else //大于3递归
	{
		if (j % fac(n - 1) == 0)//在后面数循环结束后,调换首数和后面一个数,产生新的组合
		{
			int tmp = j;
			if (tmp > fac(n))
				tmp = tmp % fac(n);//tmp要在fac(n)内,防止(1)越界

			bubble_sort(arrange + 1,n-1);//排序方便调换
			if (tmp == 0)//自然顺序做首排列,第0次
			{
				return;
			}
			if (tmp == fac(n - 1))
				change(arrange, arrange + n - 1);//调换算法,第一次换最后一位
			else
				change(arrange, arrange + n - (tmp / fac(n - 1)) + 1);//(1)之后“/”
		}
		tran_arrange(arrange+1,j,n-1);
	}
}


void build_deter(determinant *d)//创建行列式
{
	printf("请输入行列数:>");//输入行列式
	scanf("%d", &d->n);

	d->p = (int*)malloc(sizeof (int)* d->n*d->n);//为行列式分配空间
	if (d->p == NULL)
	{
		printf("%s", strerror(errno));
	}

	printf("请按行输入值:>");
	for (int i = 0; i < d->n; i++)
	{
		for (int j = 0; j < d->n; j++)
		{
			scanf("%d",(d->p)+(i*d->n+j));
		}
	}
	printf("building over!\n");
}

void dis_deter(determinant d)//打印行列式
{
	for (int i = 0; i < d.n; i++)
	{
		printf("|");
		for (int j = 0; j < d.n; j++)
		{
			printf("%-3d ", *((d.p) + (i * d.n + j)));
		}
		printf("|\n");
	}
	printf("printing over!\n");
}

int count_re(int* arrange,int n)//统计逆序数
{
	int count = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = i+1; j < n; j++)
		{
			if (arrange[i] > arrange[j])
				count++;
		}
	}
	if (count % 2 == 1)
		return -1;
	else
		return 1;
}


int count_deter(determinant d)//计算行列式
{
	int result = 0;//行列式最终结果
	int one = 1;//行列式的每个积
	int *col_arrange = (int*)malloc(sizeof(int)*d.n);//创建一个记录列排列的数组
	if (col_arrange == NULL)
	{
		printf("%s", strerror(errno));
	}

	for (int i = 0; i < d.n; i++)
	{
		*(col_arrange+i) = i;
	}//赋值

	for (int r = 0; r < fac(d.n); r++)//所有行列式的结果
	{
		one = 1;
		tran_arrange(col_arrange,r,d.n);//确定一个列的排序
		for (int i = 0; i < d.n; i++)
		{
			int a = *(d.p+(i*d.n)+col_arrange[i]);//行列式每个数
			one = a*one;
		}
		result += one* count_re(col_arrange, d.n);
	}

	free(col_arrange);
	col_arrange = NULL;
	return result;
}


void free_deter(determinant* d)//释放空间
{
	free(d->p);
	d->p = NULL;
}

int main()
{

	determinant d;
	build_deter(&d);
	dis_deter(d);
	printf("\n%d",count_deter(d));
	free_deter(&d);
	return 0;

标签:int,整数,C语言,++,行列式,printf,fac,arrange
From: https://blog.csdn.net/2301_79847688/article/details/136785390

相关文章

  • C语言的宏和预处理器
    预处理器的作用预处理器在实际编译发生之前扮演着重要的角色,它处理各种预处理指令,这些指令包括宏定义(#define)、文件包含(#include)、条件编译(#ifdef、#ifndef、#if、#else、#elif、#endif),以及编译错误(#error)和行控制(#line)。示例代码://条件编译#defineDEBUG1#......
  • 【C语言】字符函数与字符串函数以及内存函数 { 超详细攻略,一篇学会 }
    今日分享:字符、字符串函数和内存函数内存函数就是对内存进行操作的函数字符串函数就是对字符串进行操作的函数字符函数就是对字符进行操作的函数str前缀的函数是字符串函数,头文件string.hmem前缀的函数是内存函数,头文件stdlib.h字符函数与字符串函数以及内存函数......
  • C语言分支与循环(二)
    前言通过上一篇文章了解完条件分支语句中的if语句相关知识后,其实除了if语句外,C语⾔还提供了switch语句来实现分⽀结构。接下来我将介绍switch语句,废话不多说,我们直接开始吧!switch语句的基本形式switch(表达式){ case情况1: 语句块1; case情况2: 语句块2; ... ca......
  • # c语言程序设计——实验报告
    实验项目名称:实验一熟悉C语言运行环境实验项目类型:验证性实验日期:2023年3月14日一、实验目的下载安装Devc6.0程序。了解在该系统上如何进行编辑、编译、连接和运行一个C程序。通过运行简单的C程序了解C程序的特点。二、实验硬、软件环境Windows计算机、Devc6.0三、......
  • c语言程序设计--实验报告一
    实验项目名称:实验一熟悉C语言运行环境实验项目类型:验证性实验日期:2023年3月14日一、实验目的下载安装Devc6.0程序。了解在该系统上如何进行编辑、编译、连接和运行一个C程序。通过运行简单的C程序了解C程序的特点。二、实验硬、软件环境Windows计算机、Devc6.0三、......
  • C语言指针与数组(不适合初学者版):一篇文章带你深入了解指针与数组!
    ......
  • C语言指针(适合C语言进阶者):一道题带你深入理解数组与指针的关系
    ......
  • 实验1 C语言开发环境使用和数据类型、运算符、表达式
    ......
  • 实验1 C语言输入输出和简单程序编写
    实验任务1_1#include<stdio.h>intmain(){ printf("O\n"); printf("<H>\n"); printf("II\n"); printf("O\n"); printf("<H>\n"); printf("II\n"); return0;} 实验......
  • C语言 02 安装
    C语言的编译器有很多,其中最常用的是GCC,这里以安装GCC为例。Windows这里以Windows11为例官方下载地址:https://www.mingw-w64.org/选择Downloads选择Windows的GCC环境MingW-W64-builds选择GitHub根据操作系统位数进行选择(现在大多数电脑都是64......