2016-04-14 2 views
0

Я пытаюсь преобразовать this Java code (Оценивает арифметические выражения с использованием алгоритма два-стека Дейкстров) на C#:Преобразование Java в C# (Unity)

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 перестанет работать, когда я пытаюсь проверить его , Что я сделал не так?

+1

с очень кратким взглядом, кажется, вы никогда не переустанавливаете 's', и вы зацикливаете бесконечно. – Jonesopolis

+2

Как он «перестает работать»? Когда вы проходите это в отладчике, где/как именно это происходит? – David

+0

Вы называете это внутри функции обновления MonoBehaviour? – Frohlich

ответ

0

Ваш код ведет себя как ожидалось. Вы не перевели Java-код на C#. На данный момент я могу заметить одну проблему, но я не знаю, есть ли у них больше, когда вы это исправите.

Ява оригинальный код выходит Петля в то время, когда вход пуст. Ниже то, что код Java выглядит следующим образом:

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

Он использует вход к перерыв из цикла. Выходы, если вход пуст.

Ваш C# код:

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

Он использует s к перерыв из цикла в то время, но s не изменяется где-либо в цикле. Таким образом, цикл продолжается. Это приводит к бесконечному циклу и бесконечному циклу в Unity. = Заблокировать/Заморозить с несколькими исключениями.

Fix # 1. Вызвать Eval в другой теме. Не рекомендуется для новичков.

Fix # 2. Использовать Coroutine.

Мое решение с Coroutine.

Изменить тип возвращаемой функции от double до Coroutine затем положить yield return null; внутри цикла while. To call функция, использование StartCoroutine(Eval("Your Expression"));. Использование yield return null; будет предотвратить Единство от сбоев.

Даже если вы сделаете это, вы код все равно не выйти, когда вы передаете значение, которое не пусто, но это обыкновениеЗамок/Замораживание больше.

Чтобы исправить это и скопировать код с 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(); 
} 
+0

Ошибка: 'FormatException: Неизвестный символ: ( System.Double.Parse (System.String s, NumberStyles style, поставщик IFormatProvider)' – ARTAGE

+0

@ARTAGE. Мой ответ разрешит вашу проблему с замораживанием, а также предоставит возможность использовать ввод так же, как Java-код. Как я уже упоминал в начале этого, я не знаю, является ли это единственной проблемой в коде. Вы можете задать еще один вопрос, если у вас все еще есть проблемы, подобные приведенной выше ошибке. – Programmer

Смежные вопросы