2016-04-16 63 views
0

下面的代碼創建一個記憶所有操作數和操作符的計算器。「Evaluate」函數接收一個Ops數組並返回一個包含結果和剩餘操作的元組。但我無法理解交換機出現了什麼問題。return語句如何在switch中工作?

如果情況是opStack有4個x,5,+,6最後一個元素6在開關中被刪除並檢查。由於它是一個操作數,它將返回6(操作數),剩下的元素4,x,5,+。

我的理解是否正確? 「6」和「4,x,5,+」去哪裏以及整個表達如何評估?

  private enum Op { 
    case Operand (Double) 
    case UnaryOperation(String , Double -> Double) 
    case BinaryOperation(String , (Double,Double) -> Double) 
     } 
private var opStack = [Op]() 
private var knownOps = [String : Op]() 

init() { 
    knownOps["×"] = Op.BinaryOperation("×" , *) 
    knownOps["÷"] = Op.BinaryOperation("÷"){ $1/$0 } 
    knownOps["+"] = Op.BinaryOperation("+" , +) 
    knownOps["−"] = Op.BinaryOperation("−"){ $1 - $0 } 
    knownOps["√"] = Op.UnaryOperation("√" ,sqrt) 
} 

    private func evaluate(ops : [Op]) -> (result : Double? , remainingOps: [Op]){ 

    if !ops.isEmpty { 
     var remainingOps = ops 
     let op = remainingOps.removeLast() 

     switch op{ 

     case .Operand(let operand): 
      return (operand , remainingOps) 

     case .UnaryOperation(_ , let operation): 
      let operandEvaluation = evaluate(remainingOps) 
     if let operand = operandEvaluation.result{ 
      return (operation(operand), operandEvaluation.remainingOps) } 

} 
     case .BinaryOperation(_, let operation): 
      let op1Evaluation = evaluate(remainingOps) 
      if let operand1 = op1Evaluation.result { 
       let op2Evaluation = evaluate(op1Evaluation.remainingOps) 
       if let operand2 = op2Evaluation.result { 
        return (operation(operand1, operand2), op2Evaluation.remainingOps) 
       } 
      } 
     } 
      } 
    return(nil , ops) 
} 
+1

函數是遞歸的;請注意'UnaryOperation'和'BinaryOperation'事件調用'evaluate'。你可以在函數中設置一個斷點和一步,看看它是如何工作的,但是當你說操作數堆棧裏有'4,x,5,+,6'時,我懷疑你是不正確的。它看起來會有兩個操作「4x5」和「+6」 – Paulw11

回答

0

啊你在做斯坦福大學的快速講座!他們都是偉大的。當我經歷他們時,我也遇到了這個函數的一些問題。

基本上,計算器在工作方式上非常不典型,需要一點時間才能正確使用它作爲用戶。調用堆棧將返回6,在這種情況下,你是絕對正確的。然後用戶可以再次評估,但是您的調用堆棧無法正常工作。

計算器期望該流爲一個二進制運算:

用戶輸入操作數1,並將其添加到堆棧 用戶輸入操作數,並將其添加到堆棧中。 然後將用戶輸入的二進制運算符,他們想申請到操作數

所以對於二進制操作的調用堆棧看起來是這樣的:

[5,6,*]

這將評估至30

對於一元運算預計:

用戶輸入操作數,並把它添加到堆棧 用戶選擇的一元運算他們想應用到操作數

所以一元調用堆棧的樣子:

[4√]

這將評估2

是這樣工作的,在沒有操作的操作之前它在棧會結束評估運行,否則它不會理解堆棧的其餘部分(看看你的堆棧,並將其與計算器的期望相比較,你會明白我的意思)

也像@ paulw11我會高度建議設置一個佈雷阿kpoint在開始時評估並逐步運行(非常緩慢),讓您瞭解它的工作原理非常有用。

+0

謝謝,這有助於。 Y) – 209135