化学反应方程式配平

前一些日子帮朋友实现了一个化学方程式配平的程序。先是想到了用最小公倍数法实现配平。但是后来一想用质量守恒定律配平的话会更简单。

源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import re
import math


class FenZi:
AtomListSingle = [
{"id": "1", "name": "氢", "en": "H", "mass": "1.007"},
{"id": "5", "name": "硼", "en": "B", "mass": "10.811"},
{"id": "6", "name": "碳", "en": "C", "mass": "12.0107"},
{"id": "7", "name": "氮", "en": "N", "mass": "14.006"},
{"id": "8", "name": "氧", "en": "O", "mass": "15.999"},
{"id": "9", "name": "氟", "en": "F", "mass": "18.998"},
{"id": "15", "name": "磷", "en": "P", "mass": "30.973"},
{"id": "16", "name": "硫", "en": "S", "mass": "32.065"},
{"id": "19", "name": "钾", "en": "K", "mass": "39.098"},
{"id": "23", "name": "钒", "en": "V", "mass": "50.941"},
{"id": "39", "name": "钇", "en": "Y", "mass": "88.905"},
{"id": "53", "name": "碘", "en": "I", "mass": "126.904"},
{"id": "74", "name": "钨", "en": "W", "mass": "183.84"},
{"id": "92", "name": "铀", "en": "U", "mass": "238.028"}
]
AtomListDouble = [
{"id": "2", "name": "氦", "en": "He", "mass": "4.002"},
{"id": "3", "name": "锂", "en": "Li", "mass": "6.941"},
{"id": "4", "name": "铍", "en": "Be", "mass": "9.012"},
{"id": "10", "name": "氖", "en": "Ne", "mass": "20.179"},
{"id": "11", "name": "钠", "en": "Na", "mass": "22.989"},
{"id": "12", "name": "镁", "en": "Mg", "mass": "24.305"},
{"id": "13", "name": "铝", "en": "Al", "mass": "26.981"},
{"id": "14", "name": "硅", "en": "Si", "mass": "28.085"},
{"id": "17", "name": "氯", "en": "Cl", "mass": "35.453"},
{"id": "18", "name": "氩", "en": "Ar", "mass": "39.948"},
{"id": "20", "name": "钙", "en": "Ca", "mass": "40.078"},
{"id": "21", "name": "钪", "en": "Sc", "mass": "44.955"},
{"id": "22", "name": "钛", "en": "Ti", "mass": "47.867"},
{"id": "24", "name": "铬", "en": "Cr", "mass": "51.996"},
{"id": "25", "name": "锰", "en": "Mn", "mass": "54.938"},
{"id": "26", "name": "铁", "en": "Fe", "mass": "55.845"},
{"id": "27", "name": "钴", "en": "Co", "mass": "58.933"},
{"id": "28", "name": "镍", "en": "Ni", "mass": "58.693"},
{"id": "29", "name": "铜", "en": "Cu", "mass": "63.546"},
{"id": "30", "name": "锌", "en": "Zn", "mass": "65.38"},
{"id": "31", "name": "镓", "en": "Ga", "mass": "69.723"},
{"id": "32", "name": "锗", "en": "Ge", "mass": "72.64"},
{"id": "33", "name": "砷", "en": "As", "mass": "74.921"},
{"id": "34", "name": "硒", "en": "Se", "mass": "78.96"},
{"id": "35", "name": "溴", "en": "Br", "mass": "79.904"},
{"id": "36", "name": "氪", "en": "Kr", "mass": "83.798"},
{"id": "37", "name": "铷", "en": "Rb", "mass": "85.467"},
{"id": "38", "name": "锶", "en": "Sr", "mass": "87.62"},
{"id": "40", "name": "锆", "en": "Zr", "mass": "91.224"},
{"id": "41", "name": "铌", "en": "Nb", "mass": "92.906"},
{"id": "42", "name": "钼", "en": "Mo", "mass": "95.94"},
{"id": "43", "name": "锝", "en": "Tc", "mass": "97.9072"},
{"id": "44", "name": "钌", "en": "Ru", "mass": "101.07"},
{"id": "45", "name": "铑", "en": "Rh", "mass": "102.905"},
{"id": "46", "name": "钯", "en": "Pd", "mass": "106.42"},
{"id": "47", "name": "银", "en": "Ag", "mass": "107.868"},
{"id": "48", "name": "镉", "en": "Cd", "mass": "112.411"},
{"id": "49", "name": "铟", "en": "In", "mass": "114.818"},
{"id": "50", "name": "锡", "en": "Sn", "mass": "118.710"},
{"id": "51", "name": "锑", "en": "Sb", "mass": "121.760"},
{"id": "52", "name": "碲", "en": "Te", "mass": "127.60"},
{"id": "54", "name": "氙", "en": "Xe", "mass": "131.293"},
{"id": "55", "name": "铯", "en": "Cs", "mass": "132.905"},
{"id": "56", "name": "钡", "en": "Ba", "mass": "137.327"},
{"id": "57", "name": "镧", "en": "La", "mass": "138.905"},
{"id": "58", "name": "铈", "en": "Ce", "mass": "140.116"},
{"id": "59", "name": "镨", "en": "Pr", "mass": "140.907"},
{"id": "60", "name": "钕", "en": "Nd", "mass": "144.242"},
{"id": "61", "name": "钷", "en": "Pm", "mass": "145"},
{"id": "62", "name": "钐", "en": "Sm", "mass": "150.36"},
{"id": "63", "name": "铕", "en": "Eu", "mass": "151.964"},
{"id": "64", "name": "钆", "en": "Gd", "mass": "157.25"},
{"id": "65", "name": "铽", "en": "Tb", "mass": "158.925"},
{"id": "66", "name": "镝", "en": "Dy", "mass": "162.500"},
{"id": "67", "name": "钬", "en": "Ho", "mass": "164.930"},
{"id": "68", "name": "铒", "en": "Er", "mass": "167.259"},
{"id": "69", "name": "铥", "en": "Tm", "mass": "168.934"},
{"id": "70", "name": "镱", "en": "Yb", "mass": "173.04"},
{"id": "71", "name": "镥", "en": "Lu", "mass": "174.967"},
{"id": "72", "name": "铪", "en": "Hf", "mass": "178.49"},
{"id": "73", "name": "钽", "en": "Ta", "mass": "180.947"},
{"id": "75", "name": "铼", "en": "Re", "mass": "186.207"},
{"id": "76", "name": "锇", "en": "Os", "mass": "190.23"},
{"id": "77", "name": "铱", "en": "Ir", "mass": "192.217"},
{"id": "78", "name": "铂", "en": "Pt", "mass": "195.084"},
{"id": "79", "name": "金", "en": "Au", "mass": "196.966"},
{"id": "80", "name": "汞", "en": "Hg", "mass": "200.59"},
{"id": "81", "name": "铊", "en": "Tl", "mass": "204.383"},
{"id": "82", "name": "铅", "en": "Pb", "mass": "207.2"},
{"id": "83", "name": "铋", "en": "Bi", "mass": "208.980"},
{"id": "84", "name": "钋", "en": "Po", "mass": "208.982"},
{"id": "85", "name": "砹", "en": "At", "mass": "209.987"},
{"id": "86", "name": "氡", "en": "Rn", "mass": "222.017"},
{"id": "87", "name": "钫", "en": "Fr", "mass": "223"},
{"id": "88", "name": "镭", "en": "Ra", "mass": "226"},
{"id": "89", "name": "锕", "en": "Ac", "mass": "227"},
{"id": "90", "name": "钍", "en": "Th", "mass": "232.038"},
{"id": "91", "name": "镤", "en": "Pa", "mass": "231.035"},
{"id": "93", "name": "镎", "en": "Np", "mass": "238.8486"},
{"id": "94", "name": "钚", "en": "Pu", "mass": "242.8798"},
{"id": "95", "name": "镅", "en": "Am", "mass": "244.8594"},
{"id": "96", "name": "锔", "en": "Cm", "mass": "246.911"},
{"id": "97", "name": "锫", "en": "Bk", "mass": "248.9266"},
{"id": "98", "name": "锎", "en": "Cf", "mass": "252.9578"},
{"id": "99", "name": "锿", "en": "Es", "mass": "253.9656"},
{"id": "100", "name": "镄", "en": "Fm", "mass": "259.0046"},
{"id": "101", "name": "钔", "en": "Md", "mass": "260.0124"},
{"id": "102", "name": "锘", "en": "No", "mass": "261.0202"},
{"id": "103", "name": "铹", "en": "Lr", "mass": "264.0436"},
{"id": "104", "name": "卢", "en": "Rf", "mass": "269.0826"},
{"id": "105", "name": "杜", "en": "Db", "mass": "270.0904"},
{"id": "106", "name": "喜", "en": "Sg", "mass": "273.1138"},
{"id": "107", "name": "波", "en": "Bh", "mass": "274.1216"},
{"id": "108", "name": "黑", "en": "Hs", "mass": "272.106"},
{"id": "109", "name": "麦", "en": "Mt", "mass": "278.1528"},
{"id": "110", "name": "鐽", "en": "Ds", "mass": "283.1918"},
{"id": "111", "name": "錀", "en": "Rg", "mass": "282.184"},
{"id": "112", "name": "鎶", "en": "Cn", "mass": "287.223"},
{"id": "113", "name": "鉨", "en": "Nh", "mass": "286.2152"},
{"id": "114", "name": "鈇", "en": "Fl", "mass": "291.1964"},
{"id": "115", "name": "镆", "en": "Mc", "mass": "290.1888"},
{"id": "116", "name": "鉝", "en": "Lv", "mass": "295.2268"},
{"id": "117", "name": "哈", "en": "Ts", "mass": "293.2116"},
{"id": "118", "name": "普", "en": "Os", "mass": "299.2572"},
]
FenZiShi = ""
FenZiShiCn = ""
Mass = 0

def __init__(self, s):
self.FenZiShi = s
self.Mass()

def Mass(self):
self.FenZiShiCn = self.FenZiShi
self.FenZiShiCn = re.sub('(\d+)', "*\\1", self.FenZiShiCn)
self.FenZiShiCn = self.FenZiShiCn.replace("(", "+(0")
self.FenZiShiCn = self.FenZiShiCn.replace("[", "+[0")
for i in self.AtomListDouble:
self.FenZiShiCn = self.FenZiShiCn.replace(i.get("en"), "+" + i.get("mass"))
for i in self.AtomListSingle:
self.FenZiShiCn = self.FenZiShiCn.replace(i.get("en"), "+" + i.get("mass"))
self.FenZiShiCn = "0" + self.FenZiShiCn
try:
self.Mass = eval(self.FenZiShiCn)
if self.Mass == 0:
self.Mass = -1
except Exception as e:
self.Mass = -1
print(e)


def inputFZS(options):
ret = []
while 1:
f = input("请输入第%d个%s化学式(输入0进行下一步):" % (len(ret) + 1, options))
if f == "0":
if len(ret) == 0:
print("%s列表不能空", options)
continue
print("共%d个%s:" % (len(ret), options))
break
m = FenZi(f).Mass
if m == -1:
print("输入有误!重新输入")
else:
ret.append({"fzs": f, "mass": m})
return ret


def CanIGet(s, Li):
if len(Li) == 1:
for i in range(1, 10):
su = Li[0] * i
if su == s:
return [i]
elif len(Li) == 2:
for i in range(1, 10):
for j in range(1, 10):
su = Li[0] * i + Li[1] * j
if su == s:
return [i, j]
elif len(Li) == 3:
for i in range(1, 10):
for j in range(1, 10):
for k in range(1, 10):
su = Li[0] * i + Li[1] * j + Li[2] * k
if su == s:
return [i, j, k]
elif len(Li) == 4:
for i in range(1, 10):
for j in range(1, 10):
for k in range(1, 10):
for w in range(1, 10):
su = Li[0] * i + Li[1] * j + Li[2] * k + Li[3] * w
if su == s:
return [i, j, k, w]
else:
return []
return []


def PiPei(f, s):
if len(f) == 1:
for i in range(1, 10):
su = f[0] * i
ret = CanIGet(su, s)
if len(ret) == len(s):
return [[i], ret]
elif len(f) == 2:
for i in range(1, 10):
for j in range(1, 10):
su = f[0] * i + f[1] * j
ret = CanIGet(su, s)
if len(ret) == len(s):
return [[i, j], ret]
elif len(f) == 3:
for i in range(1, 10):
for j in range(1, 10):
for k in range(1, 10):
su = f[0] * i + f[1] * j + f[2] * k
ret = CanIGet(su, s)
if len(ret) == len(s):
return [[i, j, k], ret]
elif len(f) == 4:
for i in range(1, 10):
for j in range(1, 10):
for k in range(1, 10):
for w in range(1, 10):
su = f[0] * i + f[1] * j + f[2] * k + f[3] * w
ret = CanIGet(su, s)
if len(ret) == len(s):
return [[i, j, k, w], ret]
else:
return []


if __name__ == '__main__':
fyw = inputFZS("生成物")
scw = inputFZS("反应物")
mf = []
for i in fyw:
mf.append(i.get("mass"))
ms = []
for i in scw:
ms.append(i.get("mass"))
jg = PiPei(mf, ms)
jg1 = jg[0]
jg1.append(jg[1])
gys = 1
ret = [[], []]
for i in range(len(fyw)):
ret[0].append("%d%s" % (math.floor(jg[0][i] / gys), fyw[i].get("fzs")))
for i in range(len(scw)):
ret[1].append("%d%s" % (math.floor(jg[1][i] / gys), scw[i].get("fzs")))
ret1 = "+".join(ret[0]) + "=" + "+".join(ret[1])
ret = ret1.replace("1", "")
print(ret)

其中n次嵌套循环部分可以用上一篇文章中指出的方法来替换,这样会更好一些。