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信号,要保持是同一个时钟
随机推荐
- Windows 下 Apache HTTP Server 安装、配置以及与 Tomcat 的整合(附图)
如果您能点开这篇文章,说明您已对熟悉Apache HTTP Server(下文用Apache简称)配置的重要性已很清楚了,本文不在赘述,直接介入正题,请往下阅读: 为便于阅读,列出文章目录: 一.Ap ...
- php-fpm日志告警"seem busy"
php-fpm日志中出现"WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.m ...
- SSO单点登录PHP简单版
前面做了一个新项目,需要用户资源可以需要共享.由于之前没有做过这样的东西,回家之后,立马网站百度"单点登录".帖子很多,甄别之后,这里列几篇认为比较有营养. http://blog ...
- Python之路第十一天,高级(3)-Python操作 Memcached、Redis
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- Python第一天-----简单登录验证
----------------------------------------- 编写登录接口 要求:1.输入用户名密码 2.认证成功后显示欢迎信息 3.输错三次后锁定 -------------- ...
- python cmd模块练习
# encoding=utf-8 import cmd import sys # cmd模块练习 class Client(cmd.Cmd): ''' 1)cmdloop():类似与Tkinter的m ...
- Silverlight中的拖拽实现的图片上传
原文 http://blog.csdn.net/dujingjing1230/article/details/5443003 在Silverlight中因为可以直接从系统的文件夹里面拖出来一个文件直接 ...
- (十二)boost库之多线程高级特性
(十二)boost库之多线程高级特性 很多时候,线程不仅仅是执行一些耗时操作,可能我们还需要得到线程的返回值,一般的处理方法就是定义一个全局状态变量,不断轮训状态,就如我目前维护的一个项目,全局变量定 ...
- 快速配置 Samba 将 Linux 目录映射为 Windows 驱动器
原文链接 samba client ubuntu redhat ubuntu gui tools 1,列出某个IP地址所提供的共享文件夹 smbclient -L 198.168.0.1 2,在s ...
- android安卓开发问题集 XMPP篇
1.消息推送查了下资料,后面还是使用了androidpn (1)java.security.KeyStoreException: KeyStore jks implementation not fou ...