我正在尝试快速开发计算器的应用程序。
我的主要问题是我的计算器没有遵循运算符的优先级。
例如: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
}
}
}
我是新手,所以欢迎您提出宝贵建议。对不起,我英语不好。谢谢。
答案 0 :(得分:1)
首先,使用IBOutlet集合会导致按钮的意外顺序,您最好在Storyboard / XIB中使用UIView的tag属性来存储按钮的整数值,并在此处使用它而不是索引:
@IBAction func tappedNumberButton(_ sender: UIButton) {
countOnMeBrain.addNewNumber(sender.tag)
}
第二,按照您的calculateTotal方法,它可以正确计算。 唯一不正确的是方法的内部逻辑,因为它会逐步执行计算而忽略运算符的优先级。不幸的是,StackOverflow并不是帮助算法的地方。请根据需要的逻辑对其进行重写,以得到正确的结果。