2013-10-28 6 views
0

Я пишу программу, которая оценивает выражение LISP через итерацию. Выражения LISP заключаются в следующем:После преобразования оператора обратно в char из double, как его использовать?

Добавление двух и двух будет записано в LISP как: (+ 2 2). Выражение LISP (* 5 4 3 2 1) будет оцениваться до пяти факториалов.

Для этого я использую стек очередей из парного разряда. Строка вводится в оценщик, я беру каждый элемент в строке, оцениваю, является ли это оператором или операндом. Когда я достигаю «(« Мне нужно нажать текущую очередь уровня на стек и создать новую очередь для продолжения оценки. Если я дойду до «), мне нужно взять оператор из очереди текущего уровня, а затем оценить каждый операнд в этой очереди до тех пор, пока он не станет пустым, после чего я предлагаю вновь обработанный операнд в очереди следующего в стеке (выталкивая его, предлагая операнд и снова нажимая его).

Моя проблема возникает, когда я достигаю ')' и пытаюсь оценить операнд текущего уровня с текущим оператором. Я пытался:

operand = operator + opQueue.poll(); 

, но это только добавляет двойное значение оператора операнда ... :(Я знаю, что я пропускаю что-то относительно основной, но на какой-либо советы или предложения будут оценены. полный код ниже. Я считаю, что проблема заключается в конце как раз перед основнымами. Я включил весь код для попытки ясности.

import java.util.Queue; 
import java.util.LinkedList; 
import java.util.Stack; 

public class IterativeEvaluator 
{ 
    private ExpressionScanner expression; 

    public IterativeEvaluator (String expression) 
    { 
    this.expression = new ExpressionScanner(expression); 
    } 

    public double evaluate(Queue<Double> operandQueue) 
    { 
    Stack<Queue<Double>> myStack = new Stack<Queue<Double>>(); 

    char operator = ' '; 
    double operand = 0.0; 

    Queue<Double> opQueue = operandQueue; 

    // write your code here to evaluate the LISP expression iteratively 
    // you will need to use an explicit stack to push and pop context objects 

    while(expression.hasNextOperand() || expression.hasNextOperator()) 
    { 

     if(expression.hasNextOperand()) 
     { 
      operand = expression.nextOperand(); 
      opQueue.offer((double)operand); 
     } 

     if(expression.hasNextOperator()) 
     { 
      operator = expression.nextOperator(); 
      if(operator == '(') 
      { 
       myStack.push(opQueue); 
       opQueue = new LinkedList<Double>();    
      } 
      if(operator != '(' && operator != ')') 
       opQueue.offer((double)operator); 
      if(operator == ')') 
      { 
       operator = ((char)(opQueue.remove().intValue())); 

       while(opQueue.peek() != null) 
       { 
        operand = operator + opQueue.poll(); 

       } 

       opQueue = myStack.pop(); 
       if(opQueue != null) 
        opQueue.offer(operand); 

      } 

     } 


    } 

    return operand; 

    } 
    public static void main(String [] args) 
    { 
    String s = 
     "(+\t(- 6)\n\t(/\t(+ 3)\n\t\t(- \t(+ 1 1)\n\t\t\t3\n\t\t\t1)\n\t\t(*))\n\t(* 2 3 4))"; // = 16.5 
    IterativeEvaluator myEvaluator = new IterativeEvaluator(s); 
    System.out.println("Evaluating LISP Expression:\n" + s); 
    System.out.println("Value is: " + myEvaluator.evaluate(null)); 
    } 
} /* 201340 */ 

ответ

1

Вот улучшенная версия коды с некоторыми замечаниями. Я надеюсь, это Вам нужно только расширить его, если вы хотите иметь более разных операторов.

public double evaluate(Queue<Double> operandQueue) 
{ 
    // from http://docs.oracle.com/javase/7/docs/api/java/util/ArrayDeque.html 
    // "This class is likely to be faster than Stack when used as a stack, ..." 
    ArrayDeque<Queue<Double>> myStack = new ArrayDeque<>(); 

    char operator; // don't pre-initialize with nonsense value 
    double operand = Double.NaN; // not used, NaN indicates if we have an error 

    Queue<Double> opQueue = operandQueue; 

    if(!expression.hasNextOperand() && !expression.hasNextOperand()) 
     // carefully decide what to do if the entire expression is empty 
     throw new IllegalArgumentException("empty expression"); 

    // write your code here to evaluate the LISP expression iteratively 
    // you will need to use an explicit stack to push and pop context objects 
    while(expression.hasNextOperand() || expression.hasNextOperator()) 
    { 
     if(expression.hasNextOperand()) 
     { 
      operand = expression.nextOperand(); 
      opQueue.offer(operand); // cast unnecessary 
     } 
     else // expression.hasNextOperator() is implied here 
     { 
      operator = expression.nextOperator(); 
      if(operator == '(') 
      { 
       myStack.push(opQueue); 
       opQueue = new LinkedList<Double>();    
      } 
      else if(operator != ')') // using <else> we know operator!='(' 
       opQueue.offer((double)operator); 
      else // using <else> we know operator==')' 
      { 
       operator = ((char)(opQueue.remove().intValue())); 
       // get the first operand, using 0.0 here would be disastrous 
       // e.g. for multiplications 
       operand = opQueue.poll(); 
       while(opQueue.peek() != null) 
       { 
        switch(operator) 
        { 
        case '+': operand += opQueue.poll(); break; 
        case '*': operand *= opQueue.poll(); break; 
        // you got the idea ... 
        } 
       } 
       opQueue = myStack.pop(); 
       if(opQueue != null) 
        opQueue.offer(operand); 
      } 
     } 
    } 
    return operand; 
} 
+0

Благодарим вас за ввод! – Atache

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

  • Нет связанных вопросов^_^