2016-04-14 36 views
0

我想轉換this Java code(求值使用Dijkstra雙堆棧算法算術表達式)到C#:將Java與C#(統一)

using System; 
using System.Collections.Generic; 
using System.IO; 

public class Evaluate 
{ 
    public double Eval(string expression) 
    { 
     Stack<string> ops = new Stack<string>(); 
     Stack<double> vals = new Stack<double>(); 

     string s = expression; 
     while (!s.Equals("")) 
     { 
      if (s.Equals("(")) ; 
      if (s.Equals("+")) ops.Push(s); 
      else if (s.Equals("-")) ops.Push(s); 
      else if (s.Equals("*")) ops.Push(s); 
      else if (s.Equals("/")) ops.Push(s); 
      else if (s.Equals("sqrt")) ops.Push(s); 
      else if (s.Equals(")")) 
      { 
       string op = ops.Pop(); 
       double v = vals.Pop(); 
       if (op.Equals("+")) v = vals.Pop() + v; 
       else if (op.Equals("-")) v = vals.Pop() - v; 
       else if (op.Equals("*")) v = vals.Pop() * v; 
       else if (op.Equals("/")) v = vals.Pop()/v; 
       else if (op.Equals("sqrt")) v = Math.Sqrt(v); 
       vals.Push(v); 
      } 
      else vals.Push(double.Parse(s)); 
     } 
     return vals.Pop(); 
    } 
} 

但統一停止工作,當我嘗試測試它。我做錯了什麼?

+1

在一個非常簡短的一瞥,它似乎你永遠不會重新分配's',並且你無限循環。 – Jonesopolis

+2

它以什麼方式「停止工作」?當你在調試器中逐步完成時,它究竟在哪裏/如何失敗? – David

+0

你在MonoBehaviour Update函數中調用它嗎? – Frohlich

回答

0

您的代碼正常工作。您沒有將Java代碼很好地轉換爲C#。我現在可以發現一個問題,但我不知道在修復這個問題時是否還有更多問題。

Java原始碼退出 while循環如果輸入是。下面是Java代碼的樣子:

while (!StdIn.isEmpty()) { 
String s = StdIn.readString(); 
...... 
...... 
} 

它使用輸入突破出while循環。如果輸入爲空,則退出。

你的C#代碼:

while (!s.Equals("")) 
{ 
...... 
...... 
} 

它採用小號突破跳出while循環,但小號並未正在改變任何地方的循環。所以循環繼續進行。這導致Unity中的無限循環和無限循環=鎖定/凍結,幾乎沒有例外。

修復#1。在另一個線程中調用Eval。不建議初學者。

修復#2。使用協程

我的解決方案是使用協程。

將您的函數返回類型從double更改爲Coroutine然後將yield return null;放入while循環中。要請撥打的功能,請使用StartCoroutine(Eval("Your Expression"));。使用yield return null;阻止 Unity從崩潰。

即使當你這樣做,你的代碼仍然不會當您在一個非空值傳遞退出,但它不會鎖定/凍結了。

要解決這個問題並從Java複製代碼,您應該找到一種方法來通過輸入來退出程序。

轉到遊戲物體 - >UI - >輸入字段和重命名遊戲物體EvalInput;

現在使用Input字段和下面的代碼使C#代碼的外觀和功能更像Java代碼。最終結果存儲在全局變量evalResult中。

InputField evalInput; 
void Start() 
{ 
    StartCoroutine(Eval("Your Expression")); 
    evalInput = GameObject.Find("EvalInput").GetComponent<InputField>(); 
} 

double evalResult = 0; 
public IEnumerator Eval(string expression) 
{ 
    Stack<string> ops = new Stack<string>(); 
    Stack<double> vals = new Stack<double>(); 
    string s = expression; 
    while (!s.Equals("")) 
    { 
     s = evalInput.text; //Modify the string here (Empty string == Exit) 

     if (s.Equals("(")) ; 
     if (s.Equals("+")) ops.Push(s); 
     else if (s.Equals("-")) ops.Push(s); 
     else if (s.Equals("*")) ops.Push(s); 
     else if (s.Equals("/")) ops.Push(s); 
     else if (s.Equals("sqrt")) ops.Push(s); 
     else if (s.Equals(")")) 
     { 
      string op = ops.Pop(); 
      double v = vals.Pop(); 
      if (op.Equals("+")) v = vals.Pop() + v; 
      else if (op.Equals("-")) v = vals.Pop() - v; 
      else if (op.Equals("*")) v = vals.Pop() * v; 
      else if (op.Equals("/")) v = vals.Pop()/v; 
      else if (op.Equals("sqrt")) v = System.Math.Sqrt(v); 
      vals.Push(v); 
     } 
     else vals.Push(double.Parse(s)); 

     yield return null; 
    } 
    evalResult = vals.Pop(); 
} 
+0

錯誤:'FormatException:Unknown char:( System.Double.Parse(System.String s,NumberStyles style,IFormatProvider provider)' – ARTAGE

+0

@ARTAGE。我的答案將解決您的凍結問題,並提供一種使用輸入的方法,就像Java代碼就像我在開始時提到的那樣,我不知道這是否是代碼中唯一的問題,如果你仍然有問題,就像上面的錯誤一樣,你可以問另一個問題。 – Programmer