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信号,要保持是同一个时钟
随机推荐
- MySQL安装配置过程
1.下载压缩包,解压: 2: 修改 my-default.ini 文件 将一下代码前# 去掉修改成自己的地址 # These are commonly set, remove the # and s ...
- CodeForces 501B - Misha and Changing Handles
有N个改名的动作,输出改完名的最终结果. 拿map做映射 #include <iostream> #include <map> #include <string> ...
- phpstorm8 配置svn
步骤1 步骤2. 步骤3.
- js文件代码未加载或者没有js效果
问题:在页面中js文件中的代码未加载或者没有任何效果. 原因: 成功引用了js文件,但无效果或者提示未加载该文档中的代码. 可能页面引用js文件的路径存在问题 解决: 重新检查你引用的js文件的路径是 ...
- css3投影讲解、投影
迷茫了好一段时间,今天开始整理一下自己,同时也整理下新的知识. CSS3: 从头开始做起:现在在页面中用到最多的是图片/容器投影,文字投影: 接下来就总结一个投影问题: box-shadow:阴影类型 ...
- centos安装phpMyAdmin
phpMyAdmin是一个网络接口,通过它可以管理你的MySQL数据库. 首先,我们使CentOS系统RPMForge软件库的phpMyAdmin,而不是官方的CentOS 6.2库: 所以需要导入 ...
- django models 类型整理 version:1.8.3
django models 类型整理 version:1.8.3 网上百度到的最上面的一篇已经是11年的了,django变化很大,现在把1.8.3版的models类型大致整理了下贴出来 普通键部分 F ...
- Ubuntu安装与初始配置
转载请注明作者:梦里风林 更多文章查看我的个人站: ahangchen.site 适用于Ubuntu版本 14.04/16.04LTS 64位 先上图 双系统安装 划分空闲磁盘,U盘安装ubuntu ...
- MySQLBackup 使用说明
001.mysqlbackup介绍: mysqlbackup是一个热备份工具.也就是说它不像mysqldump那样给表上一个全局锁,由于mysqldump上了这个锁,所以就造成客户端只能对 数据库进行 ...
- 【stm32】ADC的规则通道和注入通道混合使用
之前完成了规则通道DMA的数据传输了,不过平时在使用ADC的时候可能就会遇到很多情况,不可能就这样简单的按规则通道来采样,DMA存储,使用数据的:可能有时候会需要立刻采样,那样我们就需要利用到注入通道 ...