引入

在今年的暑假,作者利用空闲时间阅读了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解三元一次方程组_关于实现求解三元一次方程组的小程序的一点小研究相关推荐

  1. python解一元二次方程复数_一元二次方程求解(包括复数各种情况)

    /*无聊时候写的,我想每个入门的编程都会拿着个练手把,多的不说,我们来谈谈正经的--此功能实现一元二次方程求解,复数情况,输入字符处理判断是否为数字*/ import os import math i ...

  2. 智慧物业小程序_物业小程序物业微信小程序目前功能最全的物业小程序

    原标题:物业小程序物业微信小程序目前功能最全的物业小程序 以物业管理为核心,打造智慧社区云微信小程序管理平台,已入驻腾讯海纳社区,物业微信小程序,解决传统物业管理难,乱差的问题,利用微信小程序提供一整 ...

  3. 微信公众账号后台怎么解除小程序_微信小程序解除绑定 微信小程序怎么授权...

    该如何注销小程序? 微信小程序目前无法取消,也是微信小程序最脆弱.最无助的地方.如果你确定你不想要这个小程序,你可以转移和改变主题和其中的所有信息,这样你的小程序就会变成别人的小程序,与你无关.相当于 ...

  4. 计算机毕业设计Python+uniapp基于微信小程序校园心理咨询(小程序+源码+LW)

    计算机毕业设计Python+uniapp基于微信小程序校园心理咨询(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ ...

  5. python解奥数题_【新手】小白用python解小学奥数第五集

    前言 因为工作的关系,长期教小学数学奥数,最近接触到python,学到了while:for 语句这里,于是就有了这个想法:用python解奥数题 1. 订立制作目标目标: 打印题目 输入逻辑 输出答案 ...

  6. groupdel 删除组_如何在Linux中删除组– groupdel命令

    groupdel 删除组 Linux groupdel command is used to delete a group. This is a very powerful command, so u ...

  7. 基于python的毕设难吗_毕设做个小程序 毕业设计做小程序难吗

    打算用Python做毕业设计,可以做哪些方面的? Python做毕业设计,我想谈谈我的看法,供大家参考: 1.Python web前端.您可以使用python开发网站. 2.Python网络爬虫.您可 ...

  8. 用户组及添加用户到组_如何将用户添加到组?

    用户组及添加用户到组 In Linux users may have different groups registered. By default adding a user to the Linu ...

  9. this.$router.push如何刷新页面_小程序丨微信小程序如何实现页面下拉刷新

    微信小程序蕴含着众多功能,本期将简单介绍实现页面下拉刷新的方法,通过阅读本文,读者们可以自行动手操作,在实践中认识微信小程序. 首先,我们需在json配置中写出以下配置: "enablePu ...

最新文章

  1. 【Leecode】两数相加
  2. Python中处理时间 —— time模块
  3. Proximal Algorithms 4 Algorithms
  4. RandLA-Net测试
  5. python在线教学-老男孩Python在线教学|学好Python发展如何?
  6. 检测IIS应用程序池对象 回收
  7. 第二讲 ODE欧拉数值方法
  8. 成功解决PermissionError: [WinError 5] 拒绝访问 \lib\\site-packages\\h5py\\_errors.cp38-win_amd64.pyd‘
  9. html弹出div提示自动关闭,html弹出div弹窗
  10. sql server解析xml属性为表格_[Mybatis][基础支持层]mapper xml sql 解析
  11. PXE 自动安装物理机 (DHCP服务由路由提供, 不能再配置)
  12. ai人工智能_毕竟人工智能可能不适合您
  13. 解决Nvivo自动编码问题,nvivo自动编码语言包
  14. linux罗马数字1到10怎么打,罗马数字怎么打
  15. 阿里云CTO王坚当选院士,高手的人生都是如此雷同:生命的信仰
  16. 黑苹果主机z77技嘉wifi主板,
  17. 一些chrome调试
  18. NGUI中UITable下文本内容过多无法自适应
  19. F2FS文件系统工具编译及使用方法
  20. Notepad++ 下载地址

热门文章

  1. 自己动手写个聊天机器人吧
  2. 0042-批处理自动化实践-批量改名
  3. 红米note10pro救砖红米k40g游戏增强版救砖联发科机型处理器救砖教程
  4. 31:字符串p型编码
  5. 全部汽车零部件更换周期 汽车零部件固定更换周期
  6. webOffice 常用的一些API以及其他操作
  7. AT调试及拨号上网指令
  8. 【Axure视频教程】鼠标滚动切换图片
  9. 大二开始职业规划正是时候
  10. wdr通刷固件_高手绕道 新手 菜鸟修WD硬盘 少走弯路 必出通刷和方法以及一些个人见解...