我试图了解究竟是什么问我,也许你可以给我一些关于如何思考解决这个问题的直觉。我需要用Java编写一个程序来评估Lisp算术表达式,但解决方案必须遵循特定的指令。
我需要评估这样的事情:
(+\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))
我应该实现一个上下文堆栈,这是
Stack<Queue<Double>> contextStack
所以我猜它是一堆队列。我还有一个ExpressionScanner类,它扫描字符串并查找运算符和操作数:
public class ExpressionScanner
{
private String e;
private int position;
public ExpressionScanner(String e)
{
this.e = e;
this.position = 0;
}
public boolean hasNextOperator()
{
skipWhiteSpace();
return position < e.length() && isOperator(e.charAt(position));
}
public char nextOperator()
{
skipWhiteSpace();
return e.charAt(position++);
}
public boolean hasNextOperand()
{
skipWhiteSpace();
return position < e.length() && isDigit(e.charAt(position));
}
public int nextOperand()
{
skipWhiteSpace();
int operand = 0;
while (e.charAt(position) >= '0' && e.charAt(position) <='9')
operand = 10 * operand + e.charAt(position++) - '0';
return operand;
}
private void skipWhiteSpace()
{
char c;
while (position < e.length() && ((c = e.charAt(position)) == ' ' || c == '\t' || c == '\n'))
position++;
return;
}
private static boolean isOperator(char c)
{
return c == '(' || c == '+' || c == '-' || c == '*' || c == '/' || c == ')';
}
private static boolean isDigit(char c)
{
return c >= '0' && c <= '9';
}
} /*201340*/
这是我的解决方案应该进入的地方,但我有点沮丧,因为我不知道如何使用该堆栈来实现解决方案。
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)
{
// write your code here to create an explicit context stack
char operator = ' ';
double operand = 0.0;
// write your code here to evaluate the LISP expression iteratively
// you will need to use an explicit stack to push and pop context objects
}
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 */
感谢您的帮助。
答案 0 :(得分:0)
这是解决问题的方法。
import java.util.Queue;
import java.util.LinkedList;
import java.util.Stack;
import java.util.ArrayList;
class IterativeEvaluator2
{
private ExpressionScanner expression;
public IterativeEvaluator2 (String expression)
{
this.expression = new ExpressionScanner(expression);
}
public double evaluate(Queue<Double> operandqueue)
{
// write your code here to create an explicit context stack
Stack<Queue> temp_stack = new Stack<Queue>();
char operator = ' ';
double operand = 0.0;
int a;
// 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.hasNextOperator() || expression.hasNextOperand() )
{
// Get the open bracket
if ( expression.hasNextOperator())
{
operator = expression.nextOperator() ;
if (operator == '(')
{
temp_stack.push(operandqueue);
operandqueue = new LinkedList<Double>();
}
// push the list into the stack after the closing bracket appears
else if (operator == ')')
{
if (operandqueue.size() > 1 ) {
//System.out.println("new opqueue");
//System.out.println(operandqueue);
operand = calculate(operandqueue);
System.out.println(operand);
if (temp_stack.peek() != null)
{
operandqueue = temp_stack.pop();
//System.out.println(operandqueue);
operandqueue.offer(operand);
}
}
else if (operandqueue.size() == 1)
operandqueue = temp_stack.pop();
}
// if it is another operator then it must be +,-,/,*
else
{
operandqueue.offer( (double) operator );
}
}
// else it is an operand so just put it in the queue
else
{
a= expression.nextOperand() ;
//System.out.println(a);
operandqueue.offer( (double) a );
}
}
return operand;
}
private double calculate(Queue<Double> some_queue)
{
char operator = (char) some_queue.remove().intValue();
//System.out.println(operator);
double operand1 = 0;
double operand2;
switch(operator){
case '+' : while( !some_queue.isEmpty() )
{
operand2 = some_queue.remove();
operand1 = operand1 + operand2;
}
break;
case '-' : operand1 = some_queue.remove();
//checks for negative numbers
if (some_queue.isEmpty() ){
operand1 = 0 - operand1;
}
else{
while ( !some_queue.isEmpty() )
{
operand2 = some_queue.remove();
operand1 = operand1 - operand2;
System.out.println(operand1);
}
}
break;
case '*' : if (!some_queue.isEmpty() )
{
operand1 = 1;
while ( !some_queue.isEmpty() )
{
operand2 = some_queue.remove();
operand1 = operand1*operand2;
}
}
break;
case '/' : operand1 = some_queue.remove();
if (some_queue.isEmpty() )
operand1 = 1/operand1 ;
else{
while (!some_queue.isEmpty() )
{
operand2 = some_queue.remove();
operand1 = operand1/operand2; }
}
break;
}
return operand1;
}
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
IterativeEvaluator2 myEvaluator = new IterativeEvaluator2(s);
System.out.println("Evaluating LISP Expression:\n" + s);
System.out.println("Value is: " + myEvaluator.evaluate(null));
}
} /* 201340 */