You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift化学式解析问题:带括号的摩尔质量计算结果异常

括号处理逻辑错误的修复方案:化合物摩尔质量计算

你的代码核心问题是处理括号后的乘数时,错误地将整个累计的总质量(包括括号外的元素)乘以了倍数。比如计算Mg(NO3)2时,代码会先累加Mg的质量,再累加N和3个O的质量得到totalMass = Mg + N + 3O,然后乘以2,最终得到(Mg + N + 3O)*2,而正确结果应该是Mg + (N + 3O)*2。

修复思路

  • 遇到左括号时,把当前的总质量存入栈中,然后重置当前总质量为0,专门计算括号内元素的总质量。
  • 处理完右括号和对应的乘数后,将括号内的总质量乘以乘数,再加上栈中取出的括号前的总质量,作为新的总质量。

修改后的完整代码

func calculateMolarMass() {
    var totalMass = 0.0
    var i = compoundFormula.startIndex
    var massStack: [Double] = []
    var operatorStack: [Character] = []
    var openParenthesesCount = 0
    var openSquareBracketsCount = 0
    
    while i < compoundFormula.endIndex {
        let char = compoundFormula[i]
        
        if char.isLetter {
            var elementSymbol = String(char)
            i = compoundFormula.index(after: i)
            
            while i < compoundFormula.endIndex && compoundFormula[i].isLowercase {
                elementSymbol.append(compoundFormula[i])
                i = compoundFormula.index(after: i)
            }
            
            var subscriptValue = ""
            while i < compoundFormula.endIndex && compoundFormula[i].isNumber {
                subscriptValue.append(compoundFormula[i])
                i = compoundFormula.index(after: i)
            }
            
            let elementMass = atomicMasses[elementSymbol] ?? 0.0
            let multiplier = Double(subscriptValue) ?? 1.0
            
            totalMass += elementMass * multiplier
            
        } else if char == "(" || char == "[" {
            // 保存括号前的总质量,重置当前总质量计算括号内部分
            massStack.append(totalMass)
            totalMass = 0.0
            
            operatorStack.append(char)
            i = compoundFormula.index(after: i)

            if char == "(" {
                openParenthesesCount += 1
            } else {
                openSquareBracketsCount += 1
            }

        } else if char == ")" || char == "]" {
            let openBracket: Character = char == ")" ? "(" : "["
            i = compoundFormula.index(after: i)

            while !operatorStack.isEmpty && operatorStack.last != openBracket {
                applyOperator(&totalMass, &massStack, operatorStack.removeLast())
            }

            if operatorStack.isEmpty || operatorStack.last != openBracket {
                fatalError("括号不匹配")
            }

            if char == ")" {
                openParenthesesCount -= 1
            } else {
                openSquareBracketsCount -= 1
            }

            operatorStack.removeLast() // 移除左括号

            var multiplier = 1.0
            if i < compoundFormula.endIndex && compoundFormula[i].isNumber {
                var numberString = ""
                while i < compoundFormula.endIndex && compoundFormula[i].isNumber {
                    numberString.append(compoundFormula[i])
                    i = compoundFormula.index(after: i)
                }
                multiplier = Double(numberString) ?? 1.0
            }
            
            // 括号内总质量乘以乘数,加上括号前的总质量
            let bracketInnerTotal = totalMass * multiplier
            totalMass = massStack.removeLast() + bracketInnerTotal
        }

        if openParenthesesCount < 0 || openSquareBracketsCount < 0 {
            fatalError("括号不匹配")
        }
    }

    while !operatorStack.isEmpty {
        if operatorStack.last == "(" || operatorStack.last == "[" {
            fatalError("括号不匹配")
        }
        applyOperator(&totalMass, &massStack, operatorStack.removeLast())
    }

    if openParenthesesCount != 0 || openSquareBracketsCount != 0 {
        fatalError("括号不匹配")
    }

    molarMass = totalMass
}

关键修改点说明

  1. 左括号处理:新增massStack.append(totalMass); totalMass = 0.0,将括号外已经累计的总质量暂存到栈中,重置当前总质量后专门计算括号内的元素质量。
  2. 右括号处理:将原来直接totalMass *= multiplier的逻辑,改为计算括号内总质量乘以乘数后,与栈中取出的括号前总质量相加,恢复正确的累计逻辑。

内容的提问来源于stack exchange,提问作者Monte Helm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:10:54