使用两个堆栈评估Infix算术表达式

时间:2017-02-08 01:01:09

标签: java data-structures stack infix-notation postfix

根据标题,对于这个程序,我们将使用“两个堆栈来评估来自InputStream的中缀算术表达式。它不应该创建一个完整的后缀表达式;它应该以流水线方式转换和评估,一次通过。“

package cs445.a2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;


public class InfixExpressionEvaluator {
// Tokenizer to break up our input into tokens
StreamTokenizer tokenizer;

// Stacks for operators (for converting to postfix) and operands (for
// evaluating)
StackInterface<Character> operatorStack;
StackInterface<Double> operandStack;

/**
 * Initializes the evaluator to read an infix expression from an input
 * stream.
 * @param input the input stream from which to read the expression
 */
public InfixExpressionEvaluator(InputStream input) {
    // Initialize the tokenizer to read from the given InputStream
    tokenizer = new StreamTokenizer(new BufferedReader(
                    new InputStreamReader(input)));

    // StreamTokenizer likes to consider - and / to have special meaning.
    // Tell it that these are regular characters, so that they can be parsed
    // as operators
    tokenizer.ordinaryChar('-');
    tokenizer.ordinaryChar('/');

    // Allow the tokenizer to recognize end-of-line, which marks the end of
    // the expression
    tokenizer.eolIsSignificant(true);

    // Initialize the stacks
    operatorStack = new ArrayStack<Character>();
    operandStack = new ArrayStack<Double>();
}

/**
 * Parses and evaluates the expression read from the provided input stream,
 * then returns the resulting value
 * @return the value of the infix expression that was parsed
 */
public Double evaluate() throws ExpressionError {
    // Get the first token. If an IO exception occurs, replace it with a
    // runtime exception, causing an immediate crash.
    try {
        tokenizer.nextToken();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    // Continue processing tokens until we find end-of-line
    while (tokenizer.ttype != StreamTokenizer.TT_EOL) {
        // Consider possible token types
        switch (tokenizer.ttype) {
            case StreamTokenizer.TT_NUMBER:
                // If the token is a number, process it as a double-valued
                // operand
                processOperand((double)tokenizer.nval);
                break;
            case '+':
            case '-':
            case '*':
            case '/':
            case '^':
                // If the token is any of the above characters, process it
                // is an operator
                processOperator((char)tokenizer.ttype);
                break;
            case '(':
            case '[':
                // If the token is open bracket, process it as such. Forms
                // of bracket are interchangeable but must nest properly.
                processOpenBracket((char)tokenizer.ttype);
                break;
            case ')':
            case ']':
                // If the token is close bracket, process it as such. Forms
                // of bracket are interchangeable but must nest properly.
                processCloseBracket((char)tokenizer.ttype);
                break;
            case StreamTokenizer.TT_WORD:
                // If the token is a "word", throw an expression error
                throw new ExpressionError("Unrecognized token: " +
                                tokenizer.sval);
            default:
                // If the token is any other type or value, throw an
                // expression error
                throw new ExpressionError("Unrecognized token: " +
                                String.valueOf((char)tokenizer.ttype));
        }

        // Read the next token, again converting any potential IO exception
        try {
            tokenizer.nextToken();
        } catch(IOException e) {
            throw new RuntimeException(e);
        }
    }

    // Almost done now, but we may have to process remaining operators in
    // the operators stack
    processRemainingOperators();

    // Return the result of the evaluation
    // TODO: Fix this return statement
    return null;
}

/**
 * This method is called when the evaluator encounters an operand. It
 * manipulates operatorStack and/or operandStack to process the operand
 * according to the Infix-to-Postfix and Postfix-evaluation algorithms.
 * @param operand the operand token that was encountered
 */
void processOperand(double operand) {

    // TODO: Complete this method
}

/**
 * This method is called when the evaluator encounters an operator. It
 * manipulates operatorStack and/or operandStack to process the operator
 * according to the Infix-to-Postfix and Postfix-evaluation algorithms.
 * @param operator the operator token that was encountered
 */
void processOperator(char operator) {
    // TODO: Complete this method
}

/**
 * This method is called when the evaluator encounters an open bracket. It
 * manipulates operatorStack and/or operandStack to process the open bracket
 * according to the Infix-to-Postfix and Postfix-evaluation algorithms.
 * @param openBracket the open bracket token that was encountered
 */
void processOpenBracket(char openBracket) {
    // TODO: Complete this method
}

/**
 * This method is called when the evaluator encounters a close bracket. It
 * manipulates operatorStack and/or operandStack to process the close
 * bracket according to the Infix-to-Postfix and Postfix-evaluation
 * algorithms.
 * @param closeBracket the close bracket token that was encountered
 */
void processCloseBracket(char closeBracket) {
    // TODO: Complete this method
}

/**
 * This method is called when the evaluator encounters the end of an
 * expression. It manipulates operatorStack and/or operandStack to process
 * the operators that remain on the stack, according to the Infix-to-Postfix
 * and Postfix-evaluation algorithms.
 */
void processRemainingOperators() {
    // TODO: Complete this method
}


/**
 * Creates an InfixExpressionEvaluator object to read from System.in, then
 * evaluates its input and prints the result.
 * @param args not used
 */
public static void main(String[] args) {
    System.out.println("Infix expression:");
    InfixExpressionEvaluator evaluator =
                    new InfixExpressionEvaluator(System.in);
    Double value = null;
    try {
        value = evaluator.evaluate();
    } catch (ExpressionError e) {
        System.out.println("ExpressionError: " + e.getMessage());
    }
    if (value != null) {
        System.out.println(value);
    } else {
        System.out.println("Evaluator returned null");
    }
}

}

我迷失了如何实现“void processOperand(double operand)”方法(现在只需要担心这个方法)。我知道如何使用数字/变量转换Infix到Postfix,但我不明白如何编码部分。有人能给我一个如何启动这个方法的提示吗?我还包括StackInterface类,它包含所有的push,pop,peek等。方法。

 package cs445.a2;

 import java.util.EmptyStackException;


 public interface StackInterface<E> {
/** Adds a new entry to the top of this stack.
 *  @param newEntry  An object to be added to the stack */
public void push(E newEntry);

/** Removes and returns this stack's top entry.
 *  @return  The object at the top of the stack.
 *  @throws EmptyStackException  if the stack is empty. */
public E pop() throws EmptyStackException;

/** Retrieves this stack's top entry.
 *  @return  The object at the top of the stack.
 *  @throws EmptyStackException  if the stack is empty. */
public E peek() throws EmptyStackException;

/** Detects whether this stack is empty.
 *  @return  True if the stack is empty. */
public boolean isEmpty();

/** Removes all entries from this stack. */
public void clear();

}

0 个答案:

没有答案