java - 将 Java 转换为 C# (Unity)

标签 java c# unity-game-engine

我正在尝试转换 this Java code (使用 Dijkstra 的两栈算法计算算术表达式)到 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();
    }
}

但是当我尝试测试 Unity 时它停止工作。我做错了什么?

最佳答案

您的代码的行为符合预期。你没有很好地将Java代码翻译成C#。我现在可以发现一个问题,但我不知道当你解决这个问题时是否还会出现更多问题。

如果输入为,Java 原始代码就会退出 while 循环。下面是 Java 代码的样子:

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

它使用输入打破 while 循环。如果输入为空则退出。

您的 C# 代码:

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

它使用 s打破 while 循环,但 s 在循环中的任何位置都不会被更改。所以循环继续进行。这导致了Unity中的无限循环和无限循环 = 锁定/卡住,几乎没有异常(exception)。

修复#1。在另一个线程中调用 Eval。不建议初学者使用。

修复#2。使用协程

我的解决方案是使用 Coroutine。

将函数返回类型从 double 更改为 Coroutine,然后将 yield return null; 放入 while 循环内。要调用该函数,请使用StartCoroutine(Eval("Your Expression"));。使用 yield return null;防止 Unity 崩溃。

即使您这样做,当您传入一个不为空的值时,您的代码仍然不会退出,但它不会锁定/卡住

要解决此问题并从 Java 复制代码,您应该找到一种通过输入退出程序的方法。

转到GameObject->UI->输入字段并将GameObject重命名为EvalInput

现在使用输入字段和下面的代码使 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();
}

关于java - 将 Java 转换为 C# (Unity),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36632465/

相关文章:

java-创建一个简单的带旋转的 Sprite 多边形

c# - Python 和 C# 之间的通信

c# - 如何使用 ASP.NET 和 C# 在 SQL Server 中保留换行符?

c# - 当我希望我的玩家跳跃时,他正在飞翔(Unity2d)

unity-game-engine - 我应该在 Unity 中启用对 google board 的 VR 支持吗

Java、XML事件位置字符

java - 我们可以从 java 应用程序内部限制 java 应用程序的内存吗?

java - 如何使用 mule esb 将 map 存储在磁盘上?

c# - 如何通过 WPF 中的 HitTesting 使用坐标/点获取 TreeViewItem?

ios - 将 Unity 项目与现有 Xcode swift 项目组合时出现问题