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

时间:2018-08-01 14:02:26

标签: swift calculator operator-precedence

我正在尝试快速开发计算器的应用程序。

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

例如: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
    }
}

}

我是新手,所以欢迎您提出宝贵建议。对不起,我英语不好。谢谢。

1 个答案:

答案 0 :(得分:1)

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

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

第二,按照您的calculateTotal方法,它可以正确计算。 唯一不正确的是方法的内部逻辑,因为它会逐步执行计算而忽略运算符的优先级。不幸的是,StackOverflow并不是帮助算法的地方。请根据需要的逻辑对其进行重写,以得到正确的结果。