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的更多相关文章

  1. Haskell语言学习笔记(64)Lens(4)

    安装 lens-tutorial Control.Lens.Tutorial $ cabal install lens-tutorial Installed lens-tutorial-1.0.3 P ...

  2. Molecule – 帮助你构建跨平台的 HTML5 游戏

    Molecule 框架由拥有超过五年手机游戏开发经验的游戏开发者开发.由于移动浏览器与实际的 HTML5 规范的兼容性的改进和内部硬件的自然进化,HTML5 手机游戏真正有可能流行起来. 您可能感兴趣 ...

  3. 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 ...

  4. 【LeetCode】726. Number of Atoms 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/number-o ...

  5. Molecule实现数栈至简前端开发新体验

    Keep It Simple, Stupid. 这是开发人耳熟能详的 KISS 原则,也像是一句有调侃意味的善意提醒,提醒每个前端人,简洁易懂的用户体验和删繁就简的搭建逻辑就是前端开发的至简大道. 这 ...

  6. [LeetCode] Number of Atoms 原子的个数

    Given a chemical formula (given as a string), return the count of each atom. An atomic element alway ...

  7. [Swift]LeetCode726. 原子的数量 | Number of Atoms

    Given a chemical formula (given as a string), return the count of each atom. An atomic element alway ...

  8. LeetCode Number of Atoms

    原题链接在这里:https://leetcode.com/problems/number-of-atoms/description/ 题目: Given a chemical formula (giv ...

  9. 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信号,要保持是同一个时钟

随机推荐

  1. SQL创建/修改数据库、表

    --创建表 create table 表(a1 varchar(10),a2 char(2)) --为表添加描述信息 EXECUTE sp_addextendedproperty N'MS_Descr ...

  2. 利用cookie改变背景色

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. iOS开发那些事儿(一)轮播器

    前言 市面上绝大部分的APP被打开之后映入眼帘的都是一个美轮美奂的轮播器,所以能做出一个符合需求.高效的轮播器成为了一个程序员的必备技能.所以今天的这篇博客就来谈谈轮播器这个看似简单的控件其中蕴含的道 ...

  4. [Linked List]Partition List

    Total Accepted: 53879 Total Submissions: 190701 Difficulty: Medium Given a linked list and a value x ...

  5. mysql 命令

    1.查看数据库: mysql> show databases; 2.使用数据库 mysql> use mysqldata; 3.查看数据表 mysql> show tables; 4 ...

  6. php中数字和字母生成随机字符串

    function strrand($len) { $arr = array( "0", "1", "2", "3", & ...

  7. 在IE中调试Javascript

    不管我们写代码的时候如何小心,都不可能完全避免程序中出现bug,这个时侯就需要我们在调试的时候找出错误,修改代码. Javascript是一门灵活的语言,灵活的语法和它解释执行的特性,使得Javasc ...

  8. Python成长之路_装饰器

    一.初入装饰器 1.首先呢我们有这么一段代码,这段代码假设是N个业务部门的函数 def f1(aaa): print('我是F1业务') if aaa == 'f1': return 'ok' def ...

  9. Java GC机制和对象Finalize方法的一点总结

    GC是垃圾收集的意思(Garbage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超 ...

  10. javascript中的动画的实现以及运动框架的编写(1)

    大家知道js可以做出好多很漂亮的动画,看上去很神奇,其实原理很简单,今天就讨论一下js动画的实现以及如何编写可以反复重用的运动框架. 首先做一个简单的例子,我这里有一个长50px 宽20px的长条形d ...