c语言——矩阵运算器

话不多说,上代码!!

#include<stdio.h>
#include<stdlib.h>
int n,m;
float **a;//运用二重指针,避免二维数组做函数参数时长度未定情况 ;但是要先申请空间
void input() {
	int i,j;
	printf("请输入行数:");
	scanf("%d",&n);
	printf("请输入列数:");
	scanf("%d",&m);
	printf("请输入元素:\n");
	a=(float **)malloc(sizeof(float *)*n);//申请行空间
	for(i=0; i<n; i++) {
		a[i]=(float *)malloc(sizeof(float)*m);//申请列空间
		printf("第%d行:",i+1);
		for(j=0; j<m; j++) {
			scanf("%f",&a[i][j]);
		}
	}
}
void output(float **c,int p,int q) {
	int i,j;
	for(i=0; i<p; i++) {
		printf("第%d行:",i+1);
		for(j=0; j<q; j++) {
			printf("%.1f ",c[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
void transform() {
	int i,j;
	float b[m][n];
	for(i=0; i<n; i++) {
		for(j=0; j<m; j++) {
			b[j][i]=a[i][j];
		}
	}
	for(i=0; i<m; i++) {//转置行数与列数互换
		for(j=0; j<n; j++) {
			printf("%.1f ",b[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
void add() {
	int i,j;
	float c[n][m],d[n][m];//相加维数相同;不需要再定义阶数
	printf("请输入元素:\n");
	for(i=0; i<n; i++) {
		printf("第%d行:",i+1);
		for(j=0; j<m; j++) {
			scanf("%f",&c[i][j]);
		}
	}
	for(i=0; i<n; i++) {
		for(j=0; j<m; j++) {
			d[i][j]=a[i][j]+c[i][j];
		}
	}
	printf("相加后的矩阵为:\n");
	for(i=0; i<n; i++) {
		printf("第%d行:",i+1);
		for(j=0; j<m; j++) {
			printf("%.1f ",d[i][j]);
		}
		printf("\n");
	}
}
void multiply() {
	int i,j,k,r;
	float c[m][r],d[n][r];
	printf("请输入列数:");//相乘:第一个矩阵列数与第二个矩阵行数相同
	scanf("%d",&r);
	printf("请输入元素:\n");
	for(i=0; i<m; i++) {
		printf("第%d行:",i+1);
		for(j=0; j<r; j++) {
			scanf("%f",&c[i][j]);
		}
	}
	for(i=0; i<n; i++) {
		for(j=0; j<r; j++) {
			for(k=0; k<m; k++) {
				d[i][j]+=a[i][k]*c[k][j];
			}
		}
	}
	printf("相乘后的矩阵为:\n");
	for(i=0; i<n; i++) {
		printf("第%d行:",i+1);
		for(j=0; j<r; j++) {
			printf("%.1f ",d[i][j]);
		}
		printf("\n");
	}
}
float determinant(float **c,int n) {//按第一行完全展开式计算|A|
	float det,t,**temp1;
	temp1=(float **)malloc(sizeof(float *)*(n-1));//为储存降阶矩阵开辟空间
	for(int p=0; p<n-1; p++) {
		temp1[p]=(float *)malloc(sizeof(float)*(n-1));
	}
	if(n==2) {
		det=c[0][0]*c[1][1]-c[0][1]*c[1][0];//作为终止条件; 二阶矩阵直接计算 ;
	} else {
		for(int i=0; i<n; i++) {
			for(int j=0; j<n-1; j++) {//记录第一行元素对应余子式的矩阵
				for(int k=0; k<n-1; k++) {
					temp1[j][k]=c[j+1][(k>=i)?k+1:k];//若列数小于i则不变;若列数大于等于i则向后移动一列;从而记录余子式的矩阵
				}
			}
			t=determinant(temp1,n-1);//递归计算
			if(i%2==0) {//判断余子式的正负;与第一行元素相乘;相加得行列式
				det+=c[0][i]*t;
			} else {
				det-=c[0][i]*t;
			}
		}
	}
	return det;
}
float **adjoint(float **c,int n) {//计算每一行每一列的每个元素所对应的余子式,组成A*

	float **temp2,**adj;
	if(n==2) {
		adj=(float **)malloc(sizeof(float *)*n);               //为n阶伴随矩阵开辟空间
		for(int p=0; p<n; p++) {
			adj[p]=(float *)malloc(sizeof(float)*n);
		}
		adj[0][0]=a[1][1];
		adj[0][1]=(-1)*a[1][0];
		adj[1][0]=(-1)*a[0][1];
		adj[1][1]=a[0][0];

	} else {
		temp2=(float **)malloc(sizeof(float *)*(n-1));         //为n-1阶矩阵开辟空间
		for(int p=0; p<n-1; p++) {
			temp2[p]=(float *)malloc(sizeof(float)*(n-1));
		}
		adj=(float **)malloc(sizeof(float *)*n);               //为n阶伴随矩阵开辟空间
		for(int p=0; p<n; p++) {
			adj[p]=(float *)malloc(sizeof(float)*n);
		}
		for(int i=0; i<n; i++) {//每行
			for(int j=0; j<n; j++) {//每列
				for(int k=0; k<n-1; k++) {//n-1阶矩阵
					for(int t=0; t<n-1; t++) {
						temp2[k][t]=c[(k>=i)?k+1:k][(t>=j)?t+1:t];//剔除元素所在行与列之后的矩阵
					}
				}
				adj[j][i]=determinant(temp2,n-1);//计算代数余子式Aji为  转置  后的
				if((i+j)%2==1) {//判断符号(-1)^(i+j)
					adj[j][i]=-adj[j][i];
				}
			}
		}
	}
	return adj;
}

int main() {
	float z;
	float **adj,**bt;
	int flag=1;
	do {
		printf("初始化矩阵:1\n");
		printf("打印矩阵:  2\n");
		printf("矩阵转置:  3\n");
		printf("矩阵相加:  4\n");
		printf("矩阵相乘:  5\n");
		printf("矩阵求逆:  6\n");
		printf("伴随矩阵:  7\n");
		printf("退出程序:  0\n");
		int o;
		printf("请选择功能:");
		scanf("%d",&o);
		switch(o) {
			case 1:
				printf("请输入矩阵内容:\n");
				input();
				break;
			case 2:
				printf("矩阵内容为:\n");
				output(a,n,m);
				break;
			case 3:
				printf("转置后的矩阵为:\n");
				transform();
				break;
			case 4:
				printf("请输入新矩阵:\n");
				add();
				break;
			case 5:
				printf("请输入新矩阵:\n");
				multiply();
				break;
			case 6:
				bt=adjoint(a,n);
				z=determinant(a,n);//返回行列式的值
				if(z==0) {//判断是否可逆
					printf("\n矩阵不可逆!!\n");
				} else {
					printf("逆矩阵为:\n");
					for(int i=0; i<n; i++) {
						printf("第%d行:",i+1);
						for(int j=0; j<n; j++) {
							printf("%.1f ",bt[i][j]/z);//A逆==A*/|A|
						}
						printf("\n");
					}
				}
				break;
			case 7:
				printf("伴随矩阵为:\n");
				bt=adjoint(a,n);
				output(bt,n,n);
				break;
			case 0:
				flag=0;
				printf("感谢使用!!");
				break;
			default:
				printf("\n输入错误,请重新输入!!!!\n\n");
				break;
		}
	} while(flag);
}

仅为学习过程记录。

欢迎评论指正与优化!!!!! 

 

 

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
稀疏矩阵是指矩阵中大部分元素为0的矩阵。在计算机科学中,稀疏矩阵的存储和计算是一个重要的问题。C语言可以用来实现稀疏矩阵运算。 稀疏矩阵运算的主要功能是对稀疏矩阵进行加、减、乘等运算。在实现稀疏矩阵运算时,需要考虑如何存储稀疏矩阵,如何进行矩阵运算等问题。 一种常见的稀疏矩阵存储方式是使用三元组表示法。三元组表示法将稀疏矩阵中非零元素的行、列和值存储在一个三元组中。例如,一个3x3的稀疏矩阵: 0 0 0 0 2 0 0 0 0 可以用三元组表示法表示为: row col value 1 2 2 在进行矩阵运算时,可以根据稀疏矩阵的三元组表示法进行计算。例如,两个稀疏矩阵相加时,可以先将它们的三元组表示法合并,然后按照行和列进行排序,最后进行加法运算。 以下是一个简单的C语言稀疏矩阵运算的示例代码,实现了稀疏矩阵的加法运算: ``` #include <stdio.h> #define MAX_TERMS 101 typedef struct { int row; int col; int value; } term; void sparse_add(term a[], term b[], term c[]) { int i = 0, j = 0, k = 0; while (i < a[0].value && j < b[0].value) { if (a[i].row < b[j].row || (a[i].row == b[j].row && a[i].col < b[j].col)) { c[k++] = a[i++]; } else if (a[i].row > b[j].row || (a[i].row == b[j].row && a[i].col > b[j].col)) { c[k++] = b[j++]; } else { c[k].row = a[i].row; c[k].col = a[i].col; c[k++].value = a[i++].value + b[j++].value; } } while (i < a[0].value) { c[k++] = a[i++]; } while (j < b[0].value) { c[k++] = b[j++]; } c[0].row = a[0].row; c[0].col = a[0].col; c[0].value = k - 1; } int main() { term a[MAX_TERMS] = {{3, 3, 4}, {1, 2, 2}, {2, 2, 3}, {3, 1, 1}, {3, 3, 1}}; term b[MAX_TERMS] = {{3, 3, 3}, {1, 2, 1}, {2, 2, 2}, {3, 1, 1}}; term c[MAX_TERMS]; sparse_add(a, b, c); printf("A + B =\n"); for (int i = 1; i <= c[0].value; i++) { printf("%d %d %d\n", c[i].row, c[i].col, c[i].value); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值