Molecule to atoms
For a given chemical formula represented by a string, count the number of atoms of each element contained in the molecule and return an object.
water = 'H2O'
parse_molecule(water)
# return {H: 2, O: 1}
magnesium_hydroxide = 'Mg(OH)2' parse_molecule(magnesium_hydroxide)
# return {Mg: 1, O: 2, H: 2}
var fremy_salt = 'K4[ON(SO3)2]2'
parse_molecule(fremySalt)
# return {K: 4, O: 14, N: 2, S: 4}
这个题大意就是将分子表达式转化成原子(词典表示),在codewars上难度是3kyu,难点在于各种条件的分析,防止越界,还有分子式中的各种限制。
我的思路大概就是把方括号,大括号都转换成括弧先,依次把最内层,然后外层的括弧展开,最后得到一个没有括弧的表达式,这就很好处理了。这里有个寻找最内层括弧的问题,我的理解是,先找到第一个')',然后往前找与之对应的'(',用展开后的结果代替'(...)2',我用2代替括弧后面的数字,有可能这个数字是1,自然就省略了,我们要在转换过程中把1补上。在最后的处理中,我们也要注意1是被省略的,需要计算时加上。
代码如下:
def parse_molecule(formula):
formula_dict = {}
#替换[]{}为()
for bracket in '[{':
formula = formula.replace(bracket, '(')
for bracket in ']}':
formula = formula.replace(bracket, ')')
if '(' in formula:
has_bracket = True
else:
has_bracket = False
while has_bracket:
#寻找最内层的()
for i in range(len(formula)):
if formula[i] == ')':
break
for j in range(len(formula[:i])-1, -1, -1):
if formula[j] == '(':
break
#如果有省略的1,补上
if i+1 == len(formula) or not formula[i+1].isdigit():
sub_formula = formula[j: i+1]
#为了防止后面的replace出错,设置了临时变量,否则
#如果直接sub_formula = formula[j: i+1] + '1'
#sub_formula变成了formula中没有的子串,就不执行
#这个循序就会一直进行下去
tmp = sub_formula + '
else:
sub_formula = formula[j: i+2]
tmp = sub_formula
parsed_sub_formula = parse_paren(tmp)
formula = formula.replace(sub_formula, parsed_sub_formula)
if '(' in formula:
has_bracket = True
else:
has_bracket = False
#处理没有()的分子表达式
i = 0
while i < len(formula):
j = i+1
if j < len(formula) and formula[j].islower():
j += 1
tmp = formula[i: j]
#注意边界的处理防止j越界
#我这里有个小bug,我假设的是原子下标都是最多两位,如果出现三位
#就会把第三位当做一个元素且下标为1
#没想到也通过了
if j < len(formula) and formula[j].isdigit():
k = j+1
if k < len(formula) and formula[k].isdigit():
formula_dict[tmp] = formula_dict.get(tmp, 0) + int(formula[j: k+1])
i = k+1
else:
formula_dict[tmp] = formula_dict.get(tmp, 0) + int(formula[j])
i = j+1
elif j < len(formula) and formula[j].isupper():
formula_dict[tmp] = formula_dict.get(tmp, 0) + 1
i = j
elif j == len(formula):
formula_dict[tmp] = formula_dict.get(tmp, 0) + 1
break
return formula_dict
def parse_paren(sub_formula):
result = {}
times = int(sub_formula[-1])
i = 1
while i < len(sub_formula)-2:
j = i+1
if sub_formula[j].islower():
j += 1
tmp = sub_formula[i: j]
if sub_formula[j].isdigit():
k = j+1
#此处也是假设原子下标为最多两位
if k < len(sub_formula)-2 and sub_formula[k].isdigit():
result[tmp] = result.get(tmp, 0) + int(sub_formula[j: k+1])*times
i = k+1
else:
result[tmp] = result.get(tmp, 0) + int(sub_formula[j])*times
i = j+1
elif sub_formula[j].isupper() or sub_formula[j] == ')':
result[tmp] = result.get(tmp, 0) + 1*times
i = j
t = []
for key, val in result.iteritems():
t.append(key)
t.append(str(val))
return ''.join(t)
#测试的时候故意加了一些乱七八糟的分子表达式,但还符合规则
print parse_molecule('K4[ON(SO3)2]2')
print parse_molecule('(H2O)H10')
print parse_molecule('(OH123)2')
虽然也通过了,但是代码中的bug有时间再改(不知何时了,反正被折磨得够呛,下次下次......水平太差了)
不过好像用正则表达式更好的样子,那就stay tuned...
Molecule to atoms的更多相关文章
- Haskell语言学习笔记(64)Lens(4)
安装 lens-tutorial Control.Lens.Tutorial $ cabal install lens-tutorial Installed lens-tutorial-1.0.3 P ...
- Molecule – 帮助你构建跨平台的 HTML5 游戏
Molecule 框架由拥有超过五年手机游戏开发经验的游戏开发者开发.由于移动浏览器与实际的 HTML5 规范的兼容性的改进和内部硬件的自然进化,HTML5 手机游戏真正有可能流行起来. 您可能感兴趣 ...
- Yandex 2013Q(Atoms: There and Back Again-贪心+模拟+List)
Atoms: There and Back Again Time limit 2 seconds Memory limit 256Mb Input stdin Output stdout Legend ...
- 【LeetCode】726. Number of Atoms 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/number-o ...
- Molecule实现数栈至简前端开发新体验
Keep It Simple, Stupid. 这是开发人耳熟能详的 KISS 原则,也像是一句有调侃意味的善意提醒,提醒每个前端人,简洁易懂的用户体验和删繁就简的搭建逻辑就是前端开发的至简大道. 这 ...
- [LeetCode] Number of Atoms 原子的个数
Given a chemical formula (given as a string), return the count of each atom. An atomic element alway ...
- [Swift]LeetCode726. 原子的数量 | Number of Atoms
Given a chemical formula (given as a string), return the count of each atom. An atomic element alway ...
- LeetCode Number of Atoms
原题链接在这里:https://leetcode.com/problems/number-of-atoms/description/ 题目: Given a chemical formula (giv ...
- Error (167005): Can't assign I/O pad "GX_TX" to PIN_AG27 because this causes failure in the placement of the other atoms in its associated channel
1.同时在两个GX的bank,建立两GX ip core 会出现 两个IP的cal_blk_clk信号,要保持是同一个时钟
随机推荐
- O the joy of having nothing / 아무것도 갖지않고
Chords: C G Am Em F C Dm G C G Am Em F C Am Dm G English - O the joy of having nothing and being not ...
- dojo事件
dojo.connect 和 dojo.disconnect /*建立连接*/ dojo.connect(/*Object|null*/ obj, /*String*/ event, /*Object ...
- 系统开发中按下Enter键登录系统
转载来自:http://www.jb51.net/article/54308.htm 系统开发中按下Enter键登录系统,即就是监听键盘,当按下Enter键后调用登录按钮的click()事件. JS方 ...
- 通过一张简单的图,让你搞懂JS的==运算
== 运算的规则: undefined == null,结果是true.且它俩与所有其他值比较的结果都是false. String == Boolean,需要两个操作数同时转为Number. Stri ...
- Struts2中使用Session的两种方法
在Struts2里,如果需要在Action中使用到session,可以使用下面两种方式: 通过ActionContext 类中的方法getSession得到 Action实现org.apache.st ...
- OpenCV学习笔记(一)安装及运行第一个OpenCV程序
1.下载及安装 OpenCV是一套开源免费的图形库,主要有C/C++语言编写,官网: http://opencv.org/ .在 http://opencv.org/downloads.html 可以 ...
- Java虚拟机:JVM中的Stack和Heap
简单的了解一下JVM中的栈和堆 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和 ...
- 创建文件夹并解决解决unicode和ASCII码转换的问题
# -*- coding: UTF-8 -*-import sysimport timeimport os #解决unicode和ASCII码转换的问题reload(sys) #解决unicode和A ...
- 转载【ViewPager+Fragment】ViewPager中切换界面Fragment被销毁的问题分析
ViewPager中切换界面Fragment被销毁的问题分析 原文链接 http://www.cnblogs.com/monodin/p/3866441.html 1.使用场景 ViewPager+ ...
- OTCL的多继承
Class Thing Class Animal Class Other -superclass {Animal Thing} Thing instproc init {args} { puts &q ...