2016-04-14 30 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