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 不是帮助算法的地方。请根据需要的逻辑重写它以获得正确的结果。
我正在尝试在 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 不是帮助算法的地方。请根据需要的逻辑重写它以获得正确的结果。