签到

05月06日
尚未签到

共有回帖数 0

    做月子

    等级:
    费了几天时间把以前VB贴吧上的那个化学方程式配平程序移植成C语言并新增了不少功能,现奉送给大家截屏和下载链接在下面,算法描述在楼下 ~

    *注:这不是NaylonSlain的版本,从算法到解析都是完全不同的。

    现上链接:
    核心算法源代码:http://excc.googlecode.com/files/bce-1.2.20-rc6.tar.bz2
    图形界面源代码(gambas):http://excc.googlecode.com/files/bce-gui-0.1.25.tar.bz2
    算法概要:http://excc.googlecode.com/files/XJS_BCE_KERNEL_V1.pdf
    通过下面这个例子可以说明此程序计算机配平化学方程式的过程。
    例1:配平 Na2CO3+HCl = NaCl+H2O+CO2
    设 aNa2CO3+bHCl = cNaCl+dH2O+eCO2,根据化学反应前后原子总个数不变的原理,可列方程组:
    Na: 2a = c
    C: a = e
    O: 3a = d+2e
    H: b = 2d
    Cl: b = c


    因为这个方程组没有任何常数项,故其无唯一解,设 a = 1,则可整理成完整的方程组:
    2a + 0b - 1c + 0d + 0e = 0
    1a + 0b + 0c + 0d - 1e = 0
    3a + 0b + 0c - 1d - 2e = 0
    0a + 1b + 0c - 2d + 0e = 0
    0a + 1b - 1c + 0d + 0e = 0
    1a + 0b + 0c + 0d + 0e = 1 (等同于 a = 1)


    一般地,可以用线性代数的理论解此类方程组,在90年代,加拿大科学家R.W.Jissen、W.R.Smish等已经提出了这种方法,但这些方法仍然有许多不足之处需要完善。对于解多元一次方程组,初等代数中的加减消元法已经很高效稳定且易于理解,可用于计算机算法的实现。


    使用加减消元法解多元一次方程组的一般过程是:
    将首次项系数不为零的方程的系数化成相同的数;
    通过相减消去这个未知数,并与去掉零次项的首次项系数为零的方程共同组成新的方程组
    重复上述过程,直将方程化为一元一次方程组,求得一个未知项系数并依次回代求得所有未知数的值。


    用此方法解上述方程:
    初始方程
    2a + 0b - 1c + 0d + 0e = 0
    1a + 0b + 0c + 0d - 1e = 0
    3a + 0b + 0c - 1d - 2e = 0
    0a + 1b + 0c - 2d + 0e = 0
    0a + 1b - 1c + 0d + 0e = 0
    1a + 0b + 0c + 0d + 0e = 1


    将首次项系数不为零的方程的系数化成相同的数
    6a + 0b - 3c + 0d + 0e = 0
    6a + 0b + 0c + 0d - 6e = 0
    6a + 0b + 0c - 2d - 4e = 0
    0a + 1b + 0c - 2d + 0e = 0
    0a + 1b - 1c + 0d + 0e = 0
    6a + 0b + 0c + 0d + 0e = 6


    将方程1分别与方程2、方程3、方程6相减,求得:
    0b – 3c + 0d + 6e = 0
    0b – 3c + 2d + 4e = 0
    1b + 0c – 2d + 0e = 0
    1b – 1c + 0d + 0e = 0
    0b – 3c + 0d + 0e = -6


    将方程3与方程4相减,求得:
    -3c + 0d + 6e = 0
    -3c + 2d + 4e = 0
    1c – 2d + 0e = 0
    -3c + 0d + 0e = -6


    将首次项系数不为零的方程的系数化成相同的数
    -3c + 0d + 6e = 0
    -3c + 2d + 4e = 0
    -3c + 6d + 0e = 0
    -3c + 0d + 0e = -6


    将方程1分别与方程2、方程3、方程4相减,求得:
    -2d + 2e = 0
    -6d + 6e = 0
    0d – 6e = -6


    将首次项系数不为零的方程的系数化成相同的数
    -6d + 6e = 0
    -6d + 6e = 0
    0d – 6e = -6


    方程1与方程2相同,消去,并求得:
    -6e = -6


    解得:
    e = 1


    将 e = 1 依次回代,得到a = 1、b = 2、c = 2、d = 1。
    这样就求得了方程式的配平系数,如果是分数,将其通分成整数就可以了。



    一些新特性:

    (1) 支持究级复杂的化学方程式,如:
    H2+Ca(CN)2+NaAlF4+FeSO4+MgSiO3+KI+H3PO4+PbCrO4+BrCl+CF2Cl2+SO2=PbBr2+CrCl3+MgCO3+KAl(OH)4+Fe(SCN)3+PI3+Na2SiO3+CaF2+H2O
    在此膜拜发明此化学式的大牛

    (2) 水合物支持(可以不是结合水分子)
    这个程序可以配平这样的方程式:
    Na2CO3.5H2O+H2O=Na2CO3.8H2O
    CuSO4.5H2O=CuSO4+H2O
    Cu(CN)2.2H2O=Cu(OH)2+HCN

    (3) 命令行选项控制的智能输出
    可以使用命令行选项 -f +f -s +s 等控制输出的结果的格式
    -f 表示输出配平系数
    +f 表示输出完整配平结果(包括化学方程式)
    -s 表示输出提示信息
    +s 表示不输出提示信息
    对于水合物本程序还会有智能输出,请大家自行参考make tfile生成的test.cat文件。



    在终端直接运行bce命令也可配平(当然,你要现make然后sudo make install):
    bce [命令行参数] [化学式1] [化学式2].....[化学式N]
    如:
    bce +f -s "Na2CO3+HCl=NaCl+H2O+CO2"


    顺便在此感谢化吧的某人提供的究级复杂的化学式作为测试和VB吧的某人的一些建议 && NaylonSlain的版本的部分算法。
    建议很好~ 修改的版本(程序&pdf)以后会发布的,不过请pdf和源代码一同阅读,因为刚转c,还有些BASIC思想未根除...,那个很纠结的collection链表是一个典型特征。

    parsing部分(貌似我都写在了balanceCE.c中),需要简化是一定的,我会尽可能简化。

    可能因为用了lint,所以多了很多test null的成分...see code时请无视,自认为感觉整体算法设计还可以,不过写得太复杂了。

    自认为的纠结code缺点:
    没有使用一些标准库中的东西,什么strlen,那东西返回的是size_t,不是int,直接比较就有些...(这是lint的残骸,不知道windows下是如何定义strlen的...),这些对程序整体的设计影响不是很好,所以也无视了。

    楼主 2015-11-05 12:41 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知