Swift 计算器:运算符优先级问题

Swift Calculator: operator precedence issue

我正在尝试在 swift 中开发计算器应用程序。

我的主要问题是我的计算器不遵循运算符优先级。

例如:1 + 1 * 8 = 9 //正确答案

而是:1 + 1 * 8 = 16 //在我的计算器中,这是错误的答案

我正在遵循 MVC 模式。这是我的模型:

class CountOnMeBrain {

//MARK: - Properties
var stringNumbers: [String] = [String()]
var operators: [String] = ["+"]
var index = 0
var countOnMeDelegate: CountOnMeDelegate?
var isExpressionCorrect: Bool {
    if let stringNumber = stringNumbers.last {
        if stringNumber.isEmpty {
            if stringNumbers.count == 1 {
                countOnMeDelegate?.alertShow(title: "Zéro!", message: "Démarrez un nouveau calcul!")
            } else {
                countOnMeDelegate?.alertShow(title: "Zéro!", message: "Entrez une expression correcte!")
            }
            return false
        }
    }
    return true
}

var canAddOperator: Bool {
    if let stringNumber = stringNumbers.last {
        if stringNumber.isEmpty {
            countOnMeDelegate?.alertShow(title: "Zéro!", message: "Expression incorrecte!")
            return false
        }
    }
    return true
}

//MARK: - Methods
func addNewNumber(_ newNumber: Int) {
    if let stringNumber = stringNumbers.last {
        var stringNumberMutable = stringNumber
        stringNumberMutable += "\(newNumber)"
        stringNumbers[stringNumbers.count-1] = stringNumberMutable
    }
    updateDisplay()
}

func calculateTotal() {
    if !isExpressionCorrect {
        return
    }
    var total = Double()
    for (index, stringNumber) in stringNumbers.enumerated() {
        let number = Double(stringNumber)
        switch operators[index] {
        case "+":
            total += number!
        case "-":
            total -= number!
        case "÷":
            total /= number!
        case "x":
            total *= number!
        default:
            break
        }
    }
    countOnMeDelegate?.updateTextView(label: "\(total)")
    clear()
}

func clear() {
    stringNumbers = [String()]
    operators = ["+"]
    index = 0
}

func divide() {
    if canAddOperator {
        operators.append("÷")
        stringNumbers.append("")
        updateDisplay()
    }
}

func multiply() {
    if canAddOperator {
        operators.append("x")
        stringNumbers.append("")
        updateDisplay()
    }
}

func minus() {
    if canAddOperator {
        operators.append("-")
        stringNumbers.append("")
        updateDisplay()
    }
}

func plus() {
    if canAddOperator {
        operators.append("+")
        stringNumbers.append("")
        updateDisplay()
    }
}

func updateDisplay() {
    var text = ""
    for (index, stringNumber) in stringNumbers.enumerated() {
        // Add operator
        if index > 0 {
            text += operators[index]
        }
        // Add number
        text += stringNumber
    }
    countOnMeDelegate?.updateTextView(label: text)
}

}

这是我的控制器:

class ViewController: UIViewController {

//MARK: - Outlets
@IBOutlet weak var textView: UITextView!
@IBOutlet var numberButtons: [UIButton]!
@IBOutlet var operatorButtons: UIButton!

//MARK: - Properties
var countOnMeBrain = CountOnMeBrain()

//MARK: - View Life Cycle
override func viewDidLoad() {
    super.viewDidLoad()
    countOnMeBrain.countOnMeDelegate = self
}

//MARK: - Action
@IBAction func tappedNumberButton(_ sender: UIButton) {
    for (index, numberButton) in numberButtons.enumerated() where sender == numberButton {
        countOnMeBrain.addNewNumber(index)
    }
}

@IBAction func tappedOperatorButton(_ sender: UIButton) {
    switch sender.tag {
    case 1:
        countOnMeBrain.plus()
    case 2:
        countOnMeBrain.minus()
    case 3:
        countOnMeBrain.multiply()
    case 4:
        countOnMeBrain.divide()
    case 5:
        countOnMeBrain.calculateTotal()
    default:
        break
    }
}

}

我是 swift 的初学者,欢迎大家提出宝贵意见。对不起我的英语不好。谢谢。

首先,使用 IBOutlet 集合会导致按钮的意外顺序,您最好在 Storyboard/XIB 中使用 UIView 的标签 属性 来存储按钮的整数值,并在此处使用它而不是索引:

@IBAction func tappedNumberButton(_ sender: UIButton) {
    countOnMeBrain.addNewNumber(sender.tag)
}

其次,根据您的 calculateTotal 方法,它计算正确。 唯一不正确的地方是你的方法的内部逻辑,因为它忽略了运算符的优先级,逐步执行计算。不幸的是,Whosebug 不是帮助算法的地方。请根据需要的逻辑重写它以获得正确的结果。