我正在编写一个通过迭代评估 LISP 表达式的程序。LISP 表达式如下:
将二加二在 LISP 中写为:(+ 2 2)。LISP 表达式 (* 5 4 3 2 1) 将被评估为五个阶乘。
为此,我使用了一堆双打队列。一个字符串被输入到求值器中,我取字符串中的每一项,评估它是运算符还是操作数。当我到达 '(' 我需要将当前级别队列推入堆栈并实例化一个新队列以继续评估。如果我到达 ')' 我需要从当前级别队列中获取运算符,然后评估每个该队列中的操作数直到它为空,此时我将新评估的操作数提供给堆栈中的下一个队列(通过弹出它,提供操作数,然后将其推回)。
当我到达 ')' 并尝试使用当前运算符评估当前级别操作数时,我的问题似乎出现了。我已经试了:
operand = operator + opQueue.poll();
但这只是将运算符的 double 值添加到操作数... :( 我知道我在这里遗漏了一些相对基本的东西,但是任何建议或建议将不胜感激。完整的代码如下。我相信问题出在在 main 之前结束。为了清楚起见,我包含了所有代码。
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 */