python解三元一次方程组_关于实现求解三元一次方程组的小程序的一点小研究
引入
在今年的暑假,作者利用空闲时间阅读了gilbert strange的introduction to linear algebra。作为享誉国际学界多年的MIT教材,该书以高斯消元法求解二三元方程组为开头,先介绍矩阵,随后是线性空间,再是行列式,与国内苏联风格的教材大相径庭。当时正好作者也在自学Python,便萌生出编写一个求解三元一次方程组的程序的想法。很可惜,由于暑假的时间安排的原因,这个想法最终没有实现,Python的学习也半途而废。
在大一新生军训之后,随着课程的开始,这个想法再次浮现,并且这次是以C语言来编写。
作者在阅读完C primer plus一书中的数组和指针的相关章节后,就开始着手这个项目。
初步构思
数组这种形式,可以很方便的表示矩阵,这次作者选择了三个长度为四的数组来组成矩阵。用户在程序的引导下分三次完成各个系数和等号右边常数项的输入,数据将被保存至数组中,再利用高斯消元将其化为上三角矩阵,最后回代完成求解,并将解打印在屏幕上。
数据输入
作者在完成这个部分的时候走了一个很大的弯路,因为在一开始的设计中,用户会分三次输入数据,所以将键盘输入传入数组的工作最好是由函数来完成,在main函数中直接调用三次,就可以完成工作。
但是,C语言并不允许函数返回一个数组,只能通过返回一个指向数组地址的指针,再将这个返回值赋给main函数的相应指针来实现和main函数通信(此处指针就不能直接给数组赋值了)。(1.0ver如下图)
# include
int * getcoe(void);
int main(void)
{
int * p1 = NULL;
printf("Please enter the coefficients of the first equation one by one(divide them with blank):\n");
p1 = getcoe();
printf("%d %d %d", *p1,*(p1+1),*(p1+2));//我把数组打印出来
return 0;
}
int * getcoe(void)
{
int row[3];
int * pi = NULL;
int a1,a2,a3;
scanf("%d %d %d",&a1,&a2,&a3);
row[0] = a1;
row[1] = a2;
row[2] = a3;
pi = &row[0];
return pi;
}
遵循这个复杂的思路,完成了相应的代码,然而,三次相同的调用出现了问题。由于每次函数调用的时候,系统默认的供函数使用的内存区域是相同的,导致每次main函数中的指针都指向了同一个内存区域。函数在只调用一次的情况下没有问题,但是多次调用就并不能正确地运行。(2.0ver如下图)
# include
int * getcoe(void);
int main(void)
{
int * p1 = NULL;
int * p2 = NULL;
int * p3 = NULL;
printf("Please enter the coefficients of the first equation one by one(divide them with blank):\n");
p1 = getcoe();
printf("Please enter the coefficients of the second equation one by one(divide them with blank):\n");
p2 = getcoe();
printf("Please enter the coefficients of the third equation one by one(divide them with blank):\n");
p3 = getcoe();
printf("%d %d %d\n", *p1,*(p1+1),*(p1+2));
printf("%d %d %d\n", *p2,*(p2+1),*(p2+2));
printf("%d %d %d\n", *p3,*(p3+1),*(p3+2));//我把数组打印出来
return 0;
}
int * getcoe(void)
{
int row[3];
int * pi = NULL;
int a1,a2,a3;
scanf("%d %d %d",&a1,&a2,&a3);
row[0] = a1;
row[1] = a2;
row[2] = a3;
pi = &row[0];
printf("row数组里的数值是\n");
printf("%d %d %d\n", row[0], row[1], row[2]);
printf("row数组的地址是\n");
printf("%d\n", &row[0]);
return pi;
pi = NULL;
}
运行结果(如下图)
对于每次系统分配的内存区域都一样的问题,其实可以通过动态内存分配来完成。
但是,这个程序本没有那么复杂,在与C语言程序设计课程的老师讨论之后发现,其实指针用在这个地方,反而复杂了。虽然函数不能返回指针,但是函数可以对在main函数里面定义的变量直接进行操作,这里完全无需用到函数的返回值。
发现自己走了一个大弯路之后,对输入数据程序部分重新编写,最终完成了程序。
高斯消元
高斯消元法可以将一个矩阵化为上三角矩阵或行梯阵式。通过将方程组中一个方程乘以一个系数并减去其他的方程,达到消元的目的。
回代
将矩阵化为上三角矩阵之后,就可以求出未知数Z,将Z的值回代入其他方程,就可以求解X和Y的值。
高斯消元的一些问题的解是否唯一的问题
在进行消元时,要求主元(pivot)不为零,当主元为零的时候就需要交换相应的行,使得主元位置上的系数不为零。
在解决了主元不为零的问题后,就可以正常进行高斯消元。通过对最后一行系数的检查,就可以判定该方程组是否有解、解是否唯一。如果最后一行系数全部为零,则该方程组有无数解,最后一个未知数可以取任意实数。若最后一行最后一个系数不为零(前面所有系数全为零),则该方程组无解。
最终版本的代码
根据上面所有的构思之后,最终完成了代码(3.0ver)。
代码如下
#include #define n 4
int input(float row[]);
int output(float row[]);
int main(void)
{
float a[n],b[n],c[n],d[n],e[n],f[n],ex[n];//把原有的数组高斯消元之后存进新的数组 float x, y, z;
int i;
input(a);
input(b);
input(c);
output(a);
output(b);
output(c);
putchar('\n');
if(a[0]==0)
{
if(b[0]==0)
{
for(i=0;i
{
ex[i] = a[i];
a[i] = c[i];
c[i] = ex[i];
}
}
else
{
for(i=0;i
{
ex[i] = a[i];
a[i] = b[i];
b[i] = ex[i];
}
}
output(a);
output(b);
output(c);
putchar('\n');
}
for(i=0;i
{
d[i] = b[i]-(b[0]/a[0])*a[i];//如果不用新的数组d[i]的话,b[0]/a[0]的数值会变,除非在之前把这个比值赋给一个单独变量 }
for(i=0;i
{
e[i] = c[i]-(c[0]/a[0])*a[i];
}
output(a);
output(d);
output(e);
putchar('\n');
if(d[1]==0)
{
for(i=0;i
{
ex[i] = d[i];
d[i] = e[i];
e[i] = ex[i];
}
output(a);
output(d);
output(e);
putchar('\n');
}
for(i=0;i
{
f[i] = e[i]-(e[1]/d[1])*d[i];
}
output(a);
output(d);
output(f);
putchar('\n');
if(f[2]==0)
{
if(f[3]==0)
{
printf("Sorry, the equation group you entered has infinite solutions.\n");
}
else
{
printf("Sorry, the equation group you entered has no solution.\n");
}
}
else
{
z = f[3]/f[2];//回带求值 y = (d[3]-z*d[2])/d[1];
x = (a[3]-y*a[1]-z*a[2])/a[0];
printf("x = %6.3f\ny = %6.3f\nz = %6.3f\n",x,y,z);
}
}
int input(float row[])
{
int i;
printf("Please enter the coefficients of the equation one by one(enter the form of float):\n");
for(i=0;i
{
scanf("%f",&row[i]);
}
}
int output(float row[])
{
printf("%6.3fx + %6.3fy + %6.3fz = %6.3f\n",row[0],row[1],row[2],row[3]);
putchar('\n');
}
总结
限于作者的现有水平,目前只实现了三元一次方程组的求解,这离求解n元方程组还很远。在现在的代码中,消元的代码还是不够理想,两次消元的代码是分别写出来的,如果能够用循环语句将其整合在一起,就有向n元方程组推广的可能。输入数据的函数调用也是重复写了三遍,应该有更简洁的方式。
总之,这次的代码有极大的提升空间,仍需继续学习。
致谢
首先要感谢C语言课程的姜老师,愿意并且耐心地提供了一些新思路,避免了走弯路。其次要感谢在千里之外、在百忙之中抽出时间回答各种奇怪问题的众多网友。还要感谢孟学长和宋学长,在学习之余提供了帮助。然后是刘同学,与作者一起合作探讨了这个程序,希望以后也能作为学习上的伙伴一起走下去。
写在最后
其实一开始本文是想写成一篇比较正式的小论文,奈何水平有限,在表述和排版上都未达标,最后变成了一种博客文章的感觉。在今后的学习中要多加练习书面用语和学术写作的能力,这本身也是能力的一部分。
鍦ㄥぇ涓€鏂扮敓鍐涜涔嬪悗锛岄殢鐫€璇剧▼鐨勫紑濮嬶紝杩欎釜鎯虫硶鍐嶆娴幇锛屽苟涓旇繖娆℃槸浠?/span>C璇█鏉ョ紪鍐欍€?/span>
浣滆€呭湪闃呰瀹?/span>C primer plus涓€涔︿腑鐨勬暟缁勫拰鎸囬拡鐨勭浉鍏崇珷鑺傚悗锛屽氨寮€濮嬬潃鎵嬭繖涓」鐩€?/span>
python解三元一次方程组_关于实现求解三元一次方程组的小程序的一点小研究相关推荐
- python解一元二次方程复数_一元二次方程求解(包括复数各种情况)
/*无聊时候写的,我想每个入门的编程都会拿着个练手把,多的不说,我们来谈谈正经的--此功能实现一元二次方程求解,复数情况,输入字符处理判断是否为数字*/ import os import math i ...
- 智慧物业小程序_物业小程序物业微信小程序目前功能最全的物业小程序
原标题:物业小程序物业微信小程序目前功能最全的物业小程序 以物业管理为核心,打造智慧社区云微信小程序管理平台,已入驻腾讯海纳社区,物业微信小程序,解决传统物业管理难,乱差的问题,利用微信小程序提供一整 ...
- 微信公众账号后台怎么解除小程序_微信小程序解除绑定 微信小程序怎么授权...
该如何注销小程序? 微信小程序目前无法取消,也是微信小程序最脆弱.最无助的地方.如果你确定你不想要这个小程序,你可以转移和改变主题和其中的所有信息,这样你的小程序就会变成别人的小程序,与你无关.相当于 ...
- 计算机毕业设计Python+uniapp基于微信小程序校园心理咨询(小程序+源码+LW)
计算机毕业设计Python+uniapp基于微信小程序校园心理咨询(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ ...
- python解奥数题_【新手】小白用python解小学奥数第五集
前言 因为工作的关系,长期教小学数学奥数,最近接触到python,学到了while:for 语句这里,于是就有了这个想法:用python解奥数题 1. 订立制作目标目标: 打印题目 输入逻辑 输出答案 ...
- groupdel 删除组_如何在Linux中删除组– groupdel命令
groupdel 删除组 Linux groupdel command is used to delete a group. This is a very powerful command, so u ...
- 基于python的毕设难吗_毕设做个小程序 毕业设计做小程序难吗
打算用Python做毕业设计,可以做哪些方面的? Python做毕业设计,我想谈谈我的看法,供大家参考: 1.Python web前端.您可以使用python开发网站. 2.Python网络爬虫.您可 ...
- 用户组及添加用户到组_如何将用户添加到组?
用户组及添加用户到组 In Linux users may have different groups registered. By default adding a user to the Linu ...
- this.$router.push如何刷新页面_小程序丨微信小程序如何实现页面下拉刷新
微信小程序蕴含着众多功能,本期将简单介绍实现页面下拉刷新的方法,通过阅读本文,读者们可以自行动手操作,在实践中认识微信小程序. 首先,我们需在json配置中写出以下配置: "enablePu ...
最新文章
- 【Leecode】两数相加
- Python中处理时间 —— time模块
- Proximal Algorithms 4 Algorithms
- RandLA-Net测试
- python在线教学-老男孩Python在线教学|学好Python发展如何?
- 检测IIS应用程序池对象 回收
- 第二讲 ODE欧拉数值方法
- 成功解决PermissionError: [WinError 5] 拒绝访问 \lib\\site-packages\\h5py\\_errors.cp38-win_amd64.pyd‘
- html弹出div提示自动关闭,html弹出div弹窗
- sql server解析xml属性为表格_[Mybatis][基础支持层]mapper xml sql 解析
- PXE 自动安装物理机 (DHCP服务由路由提供, 不能再配置)
- ai人工智能_毕竟人工智能可能不适合您
- 解决Nvivo自动编码问题,nvivo自动编码语言包
- linux罗马数字1到10怎么打,罗马数字怎么打
- 阿里云CTO王坚当选院士,高手的人生都是如此雷同:生命的信仰
- 黑苹果主机z77技嘉wifi主板,
- 一些chrome调试
- NGUI中UITable下文本内容过多无法自适应
- F2FS文件系统工具编译及使用方法
- Notepad++ 下载地址