按照高等代数的传统解法编写c++程序实现N(N256)元的线性方程组的求解
对于c++实现线性方程组的求解问题,前辈已经有太多的好算法。有一本书叫《C数值算法》,里面就详尽的论述了如何求解各种各样的线性方程组。
然而,前辈们的算法,无一例外几乎都是只得出一个解。面对奇异线性方程组,也只是尽量化为非奇异的线性方程组,然后解出一种解。
我笨拙,自己想了一套算法,按照高等代数人工求解线性方程组的步骤,用c++模仿人工步骤解决线性方程组的无解、一解、多解问题,并给出一解或者多解的解向量矩阵。
该程序选择从txt文档读入矩阵,并将结果输入txt文档。
(c++处理数据的难点之一,就是对矩阵的运算,实现过程是比较麻烦的。也就是数值运算的困难之处)
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;
void solution1(double [][256],int,int,string);
void solution2(double [][256],int,int,string);
int main()
{int end;while(true){cout<<"请您先在此程序所在文件目录下建立一个txt文档,文档名格式为xxx.txt"<<endl;cout<<"并且将您所要求的线性方程组的系数矩阵(或增广矩阵)整齐的输入进去"<<endl;cout<<"等您完全输入进去并且保存之后,我们再来进行接下来的工作.我等着您哦"<<endl; system("pause");cout<<"您回来了?看样子你已经输入完毕了.那我们进行接下来的工作吧"<<endl;system("pause");cout<<"请您输入您刚刚创立的txt文档名"<<endl;string filename;cin>>filename;cout<<"开始解线性方程组了哦"<<endl;int row,column;double matrix[256][256];cout<<"请您输入线性方程组的系数矩阵(或者非齐次线性方程组的增广矩阵)的行数和列数"<<endl;cin>>row;cin>>column;ifstream infile;infile.open(filename.c_str());if(!infile.is_open()){cerr<<"啊哦,出错啦.您是不是把文档名输错啦???哎!没办法啦,关闭程序从头开始吧"<<endl;}else{for(int i=0;i<row;i++){for(int j=0;j<column;j++){infile>>matrix[i][j];} } }infile.close();system("pause");int linequ;//linequ==linear equationscout<<"如果该方程组是齐次线性方程组,请您输入1"<<endl;cout<<"如果该方程组是非齐次线性方程组,请您输入2"<<endl; cout<<"您输入的是:"; cin>>linequ;if(linequ==1){solution1(matrix,row,column,filename);} if(linequ==2){solution2(matrix,row,column,filename);}if(linequ!=1&&linequ!=2){cout<<"不按要求来输入,您不乖,我不要和你玩了"<<endl;}system("pause");cout<<"如果您还想继续求解另一个线性方程组,请输入除666以外的任意整数"<<endl;cout<<"如果您想结束该程序了,请输入666"<<endl;cin>>end;if(end==666){break;} }return 0;
}
//定义求解齐次线性方程组的函数
void solution1(double a[][256],int x,int y,string filename)
{ofstream outfile;outfile.open(filename.c_str(),ios::app);if(!outfile.is_open()){cerr<<"啊哦,出错啦!结束程序从头开始吧"<<endl; }//输出线性方程组的系数矩阵 cout<<"********************************************************************************"<<endl;outfile<<endl;outfile<<"您输入的系数矩阵为:"<<endl;for(int i=0;i<x;i++){for(int j=0;j<y;j++){outfile<<a[i][j]<<"\t";}outfile<<endl;} cout<<"您输入的系数矩阵为:"<<endl; for(int i=0;i<x;i++){for(int j=0;j<y;j++){cout<<a[i][j]<<"\t";}cout<<endl;}cout<<"********************************************************************************"<<endl;outfile<<"该系数矩阵的初次行阶梯矩阵为:"<<endl;cout<<"该系数矩阵的初次行阶梯矩阵为:"<<endl;//将系数矩阵化为行阶梯矩阵int j,k=0;//j作为循环时矩阵列的变量,k作为循环时矩阵行的变量for(j=0;j<y;j++) {//对矩阵进行冒泡排序,按每列从大到小的顺序排列 for(int i=k;i<x;i++){for(int i=k;i<x;i++){if(fabs(a[i][j])<fabs(a[i+1][j])){for(int j=0;j<y;j++){double temp;temp=a[i+1][j];a[i+1][j]=a[i][j];a[i][j]=temp;}}}} //一行一行的化为行阶梯矩阵for(int i=k+1;i<x;i++){if(a[i][j]!=0){double times;times=a[i][j]/a[k][j];for(int j=0;j<y;j++){a[i][j]=a[i][j]-a[k][j]*times;} }else{int sum=0;for(int p=0;p<x;p++){if(a[p][j]==0){sum+=1;}}if(sum==2){int temp=0;for(int j=0;j<y;j++){if(a[i][j]==0){temp+=1;}}if(temp!=y){double times;times=a[i][temp]/a[i-1][temp];for(int j=0;j<y;j++){a[i][j]=a[i][j]-a[k][j]*times;}} }}}k+=1; }//输出初次化为的行阶梯矩阵for(int i=0;i<x;i++){for(int j=0;j<y;j++){outfile<<a[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<x;i++){for(int j=0;j<y;j++){cout<<a[i][j]<<"\t";}cout<<endl;}cout<<"********************************************************************************"<<endl;outfile<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl;cout<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl;//对初次行阶梯矩阵进行数据调整,减小误差for(int i=0;i<x;i++)for(int j=0;j<y;j++){if(fabs(a[i][j])<=1e-10){a[i][j]=0;}}//输出调整之后的行阶梯矩阵for(int i=0;i<x;i++){for(int j=0;j<y;j++){outfile<<a[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<x;i++){for(int j=0;j<y;j++){cout<<a[i][j]<<"\t"; }cout<<endl;} cout<<"********************************************************************************"<<endl;//求出系数矩阵的秩并输出 int r=0;for(int i=0;i<x;i++){int num=0;for(int j=0;j<y;j++){if(a[i][j]==0){num+=1;}}if(num==y){r+=1;}}r=x-r;outfile<<"二次行阶梯矩阵的秩为:"<<r<<endl; cout<<"二次行阶梯矩阵的秩为:"<<r<<endl;cout<<"********************************************************************************"<<endl;if(r==y){outfile<<"该线性方程组仅有零解"<<endl;cout<<"该线性方程组仅有零解"<<endl; }if(r<y){outfile<<"该线性方程组有非零解"<<endl;outfile<<"其解向量构成的矩阵为:"<<endl; cout<<"该线性方程组有非零解"<<endl;cout<<"其解向量构成的矩阵为:"<<endl; //利用行阶梯矩阵求解线性方程组的解向量并输出 int t;double d[y][r];//该数组存储解向量 for(t=0;t<r;t++){for(int j=0;j<y;j++){d[j][t]=0;}d[y-1-t][t]=1;for(int p=r-1;p>=0;p--){double value=0;int num=0;for(int m=0;m<y;m++){if(a[p][m]==0){num+=1;}if(a[p][m]!=0){break;}}for(int q=y-1;q>=num+1;q--){value+=a[p][q]*d[q][t];}d[num][t]=(-value)/a[p][num];}}for(int i=0;i<y;i++){for(int j=0;j<r;j++){outfile<<d[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<y;i++){for(int j=0;j<r;j++){cout<<d[i][j]<<"\t"; } cout<<endl;}cout<<"********************************************************************************"<<endl;}outfile.close();
}
//定义求解非齐次线性方程组的函数
void solution2(double a[][256],int x,int y,string filename)
{ofstream outfile;outfile.open(filename.c_str(),ios::app);if(!outfile.is_open()){cerr<<"啊哦,出错啦!结束程序从头开始吧"<<endl; }//输出线性方程组的增广矩阵 cout<<"********************************************************************************"<<endl;outfile<<"您输入的增广矩阵为:"<<endl;cout<<"您输入的增广矩阵为:"<<endl;for(int i=0;i<x;i++){for(int j=0;j<y;j++){outfile<<a[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<x;i++){for(int j=0;j<y;j++){cout<<a[i][j]<<"\t";}cout<<endl;}cout<<"********************************************************************************"<<endl;outfile<<"该增广矩阵的初次行阶梯矩阵为:"<<endl;cout<<"该增广矩阵的初次行阶梯矩阵为:"<<endl;//将增广矩阵化为行阶梯矩阵int j,k=0;//j作为循环时矩阵列的变量,k作为循环时矩阵行的变量for(j=0;j<y;j++) {//对矩阵进行冒泡排序 for(int i=k;i<x;i++){for(int i=k;i<x;i++){if(fabs(a[i][j])<fabs(a[i+1][j])){for(int j=0;j<y;j++){double temp;temp=a[i+1][j];a[i+1][j]=a[i][j];a[i][j]=temp;}}}} //一行一行的化为行阶梯矩阵for(int i=k+1;i<x;i++){if(a[i][j]!=0){double times;times=a[i][j]/a[k][j];for(int j=0;j<y;j++){a[i][j]=a[i][j]-a[k][j]*times;} }else{int sum=0;for(int p=0;p<x;p++){if(a[p][j]==0){sum+=1;}}if(sum==2){int temp=0;for(int j=0;j<y;j++){if(a[i][j]==0){temp+=1;}}if(temp!=y){double times;times=a[i][temp]/a[i-1][temp];for(int j=0;j<y;j++){a[i][j]=a[i][j]-a[k][j]*times;}} }}}k+=1; }//输出初次化为的行阶梯矩阵for(int i=0;i<x;i++){for(int j=0;j<y;j++){outfile<<a[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<x;i++){for(int j=0;j<y;j++){cout<<a[i][j]<<"\t";}cout<<endl;}cout<<"********************************************************************************"<<endl;outfile<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl; cout<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl; //对初次行阶梯矩阵进行数据调整,减小误差for(int i=0;i<x;i++)for(int j=0;j<y;j++){if(fabs(a[i][j])<=1e-10){a[i][j]=0;}}//输出调整之后的行阶梯矩阵for(int i=0;i<x;i++){for(int j=0;j<y;j++){outfile<<a[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<x;i++){for(int j=0;j<y;j++){cout<<a[i][j]<<"\t"; }cout<<endl;} cout<<"********************************************************************************"<<endl;//求出增广矩阵和系数矩阵的秩并输出 int r=0,R=0;for(int i=0;i<x;i++){int num=0;for(int j=0;j<y;j++){if(a[i][j]==0){num+=1;}}if(num==y){r+=1;}}for(int i=0;i<x;i++){int num=0;for(int j=0;j<y-1;j++){if(a[i][j]==0){num+=1;}}if(num==y-1){R+=1;} }r=x-r;R=x-R; outfile<<"二次行阶梯矩阵的秩为:"<<r<<endl;cout<<"二次行阶梯矩阵的秩为:"<<r<<endl;cout<<"********************************************************************************"<<endl;if(r<R){outfile<<"该线性方程组无解"<<endl;cout<<"该线性方程组无解"<<endl; cout<<"********************************************************************************"<<endl;}if(r==R&&r<=y){outfile<<"该线性方程组有多解"<<endl;outfile<<"其解向量构成的矩阵为:"<<endl; cout<<"该线性方程组有多解"<<endl;cout<<"其解向量构成的矩阵为:"<<endl; //利用行阶梯矩阵求解线性方程组的解向量并输出 int t;double d[y-1][r];for(t=0;t<r;t++){for(int j=0;j<y-1;j++){d[j][t]=0;}d[y-2-t][t]=1;for(int p=r-1;p>=0;p--){double value=0;int num=0;for(int m=0;m<y-1;m++){if(a[p][m]==0){num+=1;}if(a[p][m]!=0){break;}}for(int q=y-2;q>=num+1;q--){value+=a[p][q]*d[q][t];}d[num][t]=(-value)/a[p][num];}}for(int i=0;i<y-1;i++){for(int j=0;j<r;j++){outfile<<d[i][j]<<"\t";}outfile<<endl;}for(int i=0;i<y-1;i++){for(int j=0;j<r;j++){cout<<d[i][j]<<"\t"; } cout<<endl;}cout<<"********************************************************************************"<<endl;outfile<<"其特解的解向量为:"<<endl;cout<<"其特解的解向量为:"<<endl;//利用行阶梯矩阵求解线性方程组的特解double c[r],e[y-1];for(int i=0;i<r;i++){c[i]=a[i][y-1]; }for(int i=0;i<y-1;i++){e[i]=0;}e[y-2]=1;for(int p=r-1;p>=0;p--){double value=0; int num=0;for(int m=0;m<y-1;m++){if(a[p][m]==0){num+=1;}if(a[p][m]!=0){break;}}for(int q=y-2;q>=num+1;q--){value+=a[p][q]*e[q];}e[num]=(c[p]-value)/a[p][num];}for(int i=0;i<y-1;i++){outfile<<e[i]<<"\t";}for(int i=0;i<y-1;i++){cout<<e[i]<<"\t"; }cout<<endl;cout<<"********************************************************************************"<<endl; }if(r==R&&r==y){outfile<<"该线性方程组有唯一解"<<endl;outfile<<"该唯一解的解向量为:"<<endl; cout<<"该线性方程组有唯一解"<<endl;cout<<"该唯一解的解向量为:"<<endl; double m[r],n[y-1]; for(int i=0;i<r;i++){m[i]=a[i][y-2];}for(int i=0;i<y-1;i++){n[i]=0;}n[y-2]=1;for(int p=r-1;p>=0;p--){double value=0;int num=0;for(int i=0;i<y-1;i++){if(a[p][i]==0){num+=1;}if(a[p][i]!=0){break;}}for(int q=y-2;q>=0;q++){value+=n[q]*a[p][q];}n[num]=(m[p]-value)/a[p][num];}for(int i=0;i<y-1;i++){outfile<<n[i]<<"\t";}for(int i=0;i<y-1;i++){cout<<n[i]<<"\t";}cout<<endl;cout<<"********************************************************************************"<<endl; }outfile.close();
}
按照高等代数的传统解法编写c++程序实现N(N256)元的线性方程组的求解相关推荐
- C++ 编写模板程序
如何组织编写模板程序 前言 常遇到询问使用模板到底是否容易的问题,我的回答是:"模板的使用是容易的,但组织编写却不容易".看看我们几乎每天都能遇到的模板类吧,如STL, ATL, ...
- java 输入 方程,用java 编写一程序,求解一元二次方程:aX2+bX+c=0.参数a、b及c从命令行做参数输入 java...
题目: 用java 编写一程序,求解一元二次方程:aX2+bX+c=0.参数a.b及c从命令行做参数输入 java 答案参考: 以下程序在jdk5.0测试通过 import java.util.Sca ...
- 传统的Web应用程序和RESTful API
如今,当我们构建Web应用程序时,将所有功能公开为RESTful API,然后自己使用它是一种最佳实践. 这通常与使用繁重的javascript的丰富前端配合使用,例如Angular / Ember ...
- mysql 传统数据恢复_MySQL误操作后如何快速恢复数据
传统解法
利用binlog2sql快速闪回
常见问题
参考资料...
MySQL误操作后如何快速恢复数据 摘要: 利用binlog闪回误操作数据. 基本上每个跟数据库打交道的程序员(当然也可能是你同事)都会碰一个问题,MySQL误操作后如何快速回滚?比如,不小心upda ...
- 利用PROGISP实现ARDUINO IDE编写的程序的下载以及如何把AVR单片机做成ARDUINO板
首先讲讲题目的由来吧.我做的东西原本是利用ARDUINO MEGA2560及各种模块搭建起来的,程序自然也是用ARDUINO IDE写的.但这种东拼西凑的产品自然不够好,更主要的是,之前ARDUINO ...
- 用 C 语言编写的程序被称为,用c语言编写的程序被称为
快速导读: Q1:用C语言编写以下程序 #includeintmain(void){ intm,n,i,t; printf("InputM,N(int0if(scanf("%d%d ...
- C++实现类和对象:编写一个程序,模拟电梯的功能。功能接口包括电梯上行按钮、下行按钮、楼层选择和电梯在行驶过程中的楼层显示。
浙江理工大学信息学院 面向对象程序设计实验报告 实验名称:类的定义与使用 学时安排:3 实验类别:设计性实验 ...
- Fork and Join: Java也可以轻松地编写并发程序 原文地址 作者:Julien Ponge 译者:iDestiny 资源下载: Java SE 7 Sample Code(Zi
Fork and Join: Java也可以轻松地编写并发程序 原文地址 作者:Julien Ponge 译者:iDestiny 资源下载: Java SE 7 Sample Code(Zip) ...
- 编写一个c语言程序 求e的值,编写一个程序求e的值_相关文章专题_写写帮文库
时间:2019-05-15 01:58:18 作者:admin 3.2 代数式的值 做课人 尹圣军 [教学目标] 知识与技能 能解释代数式值的实际意义,了解代数式值的概念. 过程与方法 经历观察.实验 ...
最新文章
- JAVA的面向对象编程总结(第一部分)~
- centos mysql卸载重装_centos 7.x 安装/卸载MySQL
- Android 简单基站定位程序
- linux逻辑分区最小值,linux 逻辑卷管理 调整分区大小
- C++实现具有[数组]相似特征的类DoubleSubscriptArray
- 创建应用 django
- Python 3.8.0 发布!
- 剑指offer面试题66. 构建乘积数组
- 六种方法帮你解决模型过拟合问题
- 【python】os 模块使用笔记
- jquery radio,select相关操作
- Windows Server 2012 R2 Update 64位 MSDN原版
- 蓝桥杯c语言用什么编译软件,蓝桥杯c语言软件大赛
- 小程序携带参数跳转的方式wx.navigateTo的URL和通过data-传递
- 知云文献翻的一些使用
- linux虚拟主机用织梦,织梦程序用什么虚拟主机好
- 基于STM32F4 的OLED屏显示噪点、花屏问题
- Kuerbernetes 1.11 二进制安装
- 大数据基础之常用Linux命令
- 使用OpenCV和C++实现的分水岭算法(Watershed)
热门文章
- mysql ne_eq相等 ne、neq不相等, gt大于, lt小于 gte、ge大于等于 lte、le 小于等于 not非 mod求模 等...
- Python二级考试题目及答案解析(含刷题软件)
- 产品经理应掌握软件技能
- 三菱PLC MC协议简析
- 清华师姐网盘大曝光(整整400集python学习资料,真香)
- python 合并word文档,实现同一个文件夹下面的word合并成一个word
- pixelXL 下载编译源代码刷机烧录记录
- 【PR 2021】Progressive sample mining and representation learning for one-shot person re-identification
- 二十二、D触发器、T触发器、JK触发器设计总结
- matlab 王家文,基于matlab的交通标志自动识别系统