• kotlin完成 Code War 题目 解析分子公式


    题目

    对于由字符串表示的给定化学式,计算分子中包含的每个元素的原子数并返回一个对象:Java 中的 Map

    例如:

    var water = 'H2O';
    parseMolecule(water); // return {H: 2, O: 1}
    
    var magnesiumHydroxide = 'Mg(OH)2';
    parseMolecule(magnesiumHydroxide); // return {Mg: 1, O: 2, H: 2}
    
    var fremySalt = 'K4[ON(SO3)2]2';
    parseMolecule(fremySalt); // return {K: 4, O: 14, N: 2, S: 4}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如您所见,某些公式中包含括号。括号外的索引告诉您,您必须在该索引上乘以括号内每个原子的计数。例如,在 Fe(NO3)2 中有一个铁原子、两个氮原子和六个氧原子。

    请注意,括号可以是圆形、方形或卷曲的,也可以是嵌套的。大括号后的索引是可选的。

    本题我解得非常复杂,在我提交之后看到有更好的答案, 这里分享一下我认为不错的答案。

    解题思路

    • 逆向for循环公式
      • 这样的话,只需要用大写字母做结束符
    • 使用list作为栈来解决括号带来的叠加问题
    • 使用正则来判断是否合法

    解题代码:

    fun getAtomsRepeat(formula: String):Map<String, Int>{
        val counter = mutableMapOf<String, Int>()
        var atom = ""
        var digit = ""
        val numbers = mutableListOf(1)
        
        if ("\\{\\w*[\\]\\)]|\\(\\w*[\\]\\}]|\\[\\w*[\\}\\)]".toRegex().containsMatchIn(formula) ||
            formula.replace("\\w".toRegex(), "").length % 2 != 0) throw IllegalArgumentException()
    
        for(char in formula.reversed()){
            when{
                char in listOf(')', ']', '}') -> {
                    numbers.add(digit.toIntOrNull()?:1)
                    digit = ""
                }
                char in listOf('(','[', '{') -> numbers.removeAt(numbers.lastIndex)
                char.isDigit() -> digit = "$char$digit"
                char.isLowerCase() -> atom = "$char$atom"
                char.isUpperCase() ->{
                    atom = "$char$atom"
                    val number = numbers.reduce(Int::times) * (digit.toIntOrNull()?:1)
                    counter[atom] = counter[atom]?.let { it+number }?:number
                    digit = ""
                    atom = ""
                }
            }
            println("当前char:$char atom:$atom numbers:$numbers digit:$digit counter:${counter}")
        }
        return counter
    }
    
    fun main() {
        println(getAtomsRepeat("As2{Be4C5[BCo3(CO2)3]2}4Cu15"))
    //    println(getAtomsRepeat(")5"))
    }
    
    • 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
  • 相关阅读:
    SAP 后台配置之FM基金管理篇
    JavaBean 和 Spring Bean的区别
    FAT12文件系统
    前后缀表达式求值顺序栈C语言
    ADS8866 ADC转换芯片驱动调试
    【考研数学】全程跟张宇,《1000题》应该怎么搭配《660》《880》?
    如何让论文成为一篇可发表的期刊文章?
    一文入魂:再也不用担心我不懂C++移动语义了!
    Java获取时间戳、字符串和Date对象的相互转换、日期时间格式化、获取年月日
    Zookeeper系列文章—入门
  • 原文地址:https://blog.csdn.net/leidashuaige/article/details/127694589