对于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)元的线性方程组的求解相关推荐

  1. C++ 编写模板程序

    如何组织编写模板程序 前言 常遇到询问使用模板到底是否容易的问题,我的回答是:"模板的使用是容易的,但组织编写却不容易".看看我们几乎每天都能遇到的模板类吧,如STL, ATL, ...

  2. 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 ...

  3. 传统的Web应用程序和RESTful API

    如今,当我们构建Web应用程序时,将所有功能公开为RESTful API,然后自己使用它是一种最佳实践. 这通常与使用繁重的javascript的丰富前端配合使用,例如Angular / Ember ...

  4. mysql 传统数据恢复_MySQL误操作后如何快速恢复数据 传统解法 利用binlog2sql快速闪回 常见问题 参考资料...

    MySQL误操作后如何快速恢复数据 摘要: 利用binlog闪回误操作数据. 基本上每个跟数据库打交道的程序员(当然也可能是你同事)都会碰一个问题,MySQL误操作后如何快速回滚?比如,不小心upda ...

  5. 利用PROGISP实现ARDUINO IDE编写的程序的下载以及如何把AVR单片机做成ARDUINO板

    首先讲讲题目的由来吧.我做的东西原本是利用ARDUINO MEGA2560及各种模块搭建起来的,程序自然也是用ARDUINO IDE写的.但这种东拼西凑的产品自然不够好,更主要的是,之前ARDUINO ...

  6. 用 C 语言编写的程序被称为,用c语言编写的程序被称为

    快速导读: Q1:用C语言编写以下程序 #includeintmain(void){ intm,n,i,t; printf("InputM,N(int0if(scanf("%d%d ...

  7. C++实现类和对象:编写一个程序,模拟电梯的功能。功能接口包括电梯上行按钮、下行按钮、楼层选择和电梯在行驶过程中的楼层显示。

    浙江理工大学信息学院 面向对象程序设计实验报告 实验名称:类的定义与使用                      学时安排:3 实验类别:设计性实验                          ...

  8. 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) ...

  9. 编写一个c语言程序 求e的值,编写一个程序求e的值_相关文章专题_写写帮文库

    时间:2019-05-15 01:58:18 作者:admin 3.2 代数式的值 做课人 尹圣军 [教学目标] 知识与技能 能解释代数式值的实际意义,了解代数式值的概念. 过程与方法 经历观察.实验 ...

最新文章

  1. JAVA的面向对象编程总结(第一部分)~
  2. centos mysql卸载重装_centos 7.x 安装/卸载MySQL
  3. Android 简单基站定位程序
  4. linux逻辑分区最小值,linux 逻辑卷管理 调整分区大小
  5. C++实现具有[数组]相似特征的类DoubleSubscriptArray
  6. 创建应用 django
  7. Python 3.8.0 发布!
  8. 剑指offer面试题66. 构建乘积数组
  9. 六种方法帮你解决模型过拟合问题
  10. 【python】os 模块使用笔记
  11. jquery radio,select相关操作
  12. Windows Server 2012 R2 Update 64位 MSDN原版
  13. 蓝桥杯c语言用什么编译软件,蓝桥杯c语言软件大赛
  14. 小程序携带参数跳转的方式wx.navigateTo的URL和通过data-传递
  15. 知云文献翻的一些使用
  16. linux虚拟主机用织梦,织梦程序用什么虚拟主机好
  17. 基于STM32F4 的OLED屏显示噪点、花屏问题
  18. Kuerbernetes 1.11 二进制安装
  19. 大数据基础之常用Linux命令
  20. 使用OpenCV和C++实现的分水岭算法(Watershed)

热门文章

  1. mysql ne_eq相等 ne、neq不相等, gt大于, lt小于 gte、ge大于等于 lte、le 小于等于 not非 mod求模 等...
  2. Python二级考试题目及答案解析(含刷题软件)
  3. 产品经理应掌握软件技能
  4. 三菱PLC MC协议简析
  5. 清华师姐网盘大曝光(整整400集python学习资料,真香)
  6. python 合并word文档,实现同一个文件夹下面的word合并成一个word
  7. pixelXL 下载编译源代码刷机烧录记录
  8. 【PR 2021】Progressive sample mining and representation learning for one-shot person re-identification
  9. 二十二、D触发器、T触发器、JK触发器设计总结
  10. matlab 王家文,基于matlab的交通标志自动识别系统