获取Java程序以读取括号,括号和花括号

时间:2014-11-05 21:51:56

标签: java java.util.scanner

我正在编写一个验证算术表达式正确形成的程序。 (例如:正确的表单"2 + (2-1)",不正确的表单")2+(2-1"

一旦验证,程序将计算结果。

目前,它可以轻松地计算括号中的任何内容。但是如果涉及括号(例如,"2 [ 3 + (1) ]")程序验证表达式是否正确,但无法计算结果。

以下是我关注的代码

void postfixExpression() {
    stk.clear(); // Re-using the stack object
    Scanner scan = new Scanner(expression);
    char current;
    // The algorithm for doing the conversion.... Follow the bullets
    while (scan.hasNext()) {
        String token = scan.next();

        if (isNumber(token)) 
        {
            postfix = postfix + token + " ";
        } else {
            current = token.charAt(0);

            if (isParentheses(current))
            {
                if (stk.empty() || current == Constants.LEFT_NORMAL) {

                    // push this element on the stack;
                    stk.push(new Character(current));
                } else if (current == Constants.RIGHT_NORMAL) {
                    try {

                        Character ch = (Character) stk.pop();
                        char top = ch.charValue();

                        while (top != Constants.LEFT_NORMAL) {
                            postfix = postfix + top + " ";
                            ch = (Character) stk.pop();
                            top = ch.charValue();
                        }

                    } catch (EmptyStackException e) {

                    }
                }
            } else if (isOperator(current))//
            {
                if (stk.empty()) {
                    stk.push(new Character(current));
                } else {
                    try {


                        char top = (Character) stk.peek();
                        boolean higher = hasHigherPrecedence(top, current);

                        while (top != Constants.LEFT_NORMAL && higher) {
                            postfix = postfix + stk.pop() + " ";
                            top = (Character) stk.peek();
                        }
                        stk.push(new Character(current));
                    } catch (EmptyStackException e) {
                        stk.push(new Character(current));
                    }
                }
            }// Bullet # 3 ends

        }
    } // Outer loop ends

    try {
        while (!stk.empty()) // Bullet # 4
        {
            postfix = postfix + stk.pop() + " ";
        }
    } catch (EmptyStackException e) {

    }
 }

我创建了两个方法:isBracket和isCurly。起初,我认为最合适的解决方案是以与isParentheses相同的方式包含这两种方法。像这样:

 if (isParentheses(current))
            {
                if (stk.empty() || current == Constants.LEFT_NORMAL) {

                    // push this element on the stack;
                    stk.push(new Character(current));
                } else if (current == Constants.RIGHT_NORMAL) {
                    try {

                        Character ch = (Character) stk.pop();
                        char top = ch.charValue();

                        while (top != Constants.LEFT_NORMAL) {
                            postfix = postfix + top + " ";
                            ch = (Character) stk.pop();
                            top = ch.charValue();
                        }

                    } catch (EmptyStackException e) {

                    }
                }

            if (isCurly(current)) 
            {
                if (stk.empty() || current == Constants.LEFT_CURLY) {

                    // push this element on the stack;
                    stk.push(new Character(current));
                } else if (current == Constants.RIGHT_CURLY) {
                    try {

                        Character ch = (Character) stk.pop();
                        char top = ch.charValue();

                        while (top != Constants.LEFT_CURLY) {
                            postfix = postfix + top + " ";
                            ch = (Character) stk.pop();
                            top = ch.charValue();
                        }

                    } catch (EmptyStackException e) {


 if (isBracket(current)) 
            {
                if (stk.empty() || current == Constants.LEFT_SQUARE) {

                    // push this element on the stack;
                    stk.push(new Character(current));
                } else if (current == Constants.RIGHT_SQUARE) {
                    try {

                        Character ch = (Character) stk.pop();
                        char top = ch.charValue();

                        while (top != Constants.LEFT_SQUACRE) {
                            postfix = postfix + top + " ";
                            ch = (Character) stk.pop();
                            top = ch.charValue();
                        }

                    } catch (EmptyStackException e) {

但该程序仍然不会考虑括号和括号(但它仍然可以正确读取括号。)

我没有按照我的理解正确使用这些方法,但我怎样才能正确使用它们?

1 个答案:

答案 0 :(得分:0)

这是我想到的一个想法,采取不同的方法解决这个问题。

您可以将数字和括号分成两个不同的堆栈,以便更容易确保表达式正确形成。

在代码的开头,您可以声明两个堆栈变量:

Stack<Integer> numbers = new Stack<Integer>();
Stack<Character> operators = new Stack<Character>();

然后相应地推送运营商和号码。

这是我创建的一个非常快速的方法,它将演示使用两个Stack对象的实现:

public double doCalculation(String input) throws DataFormatException {
    if (input == null) {
        return 0;
    }

    char[] characters = input.toCharArray();

    for (char character: characters) {
        try {
            // tries to push the number onto the number stack
            numbers.push(Integer.parseInt("" + character));

        } catch (NumberFormatException e1) {
            // if this is caught, this means the character is non-numerical
            operators.push(character);

        }
    }

    while (operators.size() > 0) {
        int i = numbers.pop();
        int j = numbers.pop();
        char operator = operators.pop();

        switch (operator) {
            case '+':
                numbers.push(j + i);
                break;
            case '-':
                numbers.push(j - i);
                break;
            case '*':
                numbers.push(j * i);
                break;
            case '/':
                numbers.push(j / i);
                break;
            case '^':
                numbers.push((int)(Math.pow(j, i)));
                break;
            default:
                throw new DataFormatException();
        }
    }

    return numbers.pop();
}

只是为了好玩: 如果在将非数字字符推入堆栈之前将此代码添加到catch块,它将按操作顺序计算等式:

char top;
try {
    top = operators.peek();
} catch (EmptyStackException e2) {
    operators.push(character);
    continue;
}

if (getValue(character) > getValue(top)) {
    operators.push(character);
    continue;
} else {
    try {
        while (!(getValue(character) > getValue(operators.peek()))) {
            char operator;

            operator = operators.pop();

            int i = numbers.pop();
            int j = numbers.pop();

            switch (operator) {
                case '+':
                    numbers.push(j + i);
                    break;
                case '-':
                    numbers.push(j - i);
                    break;
                case '*':
                    numbers.push(j * i);
                    break;
                case '/':
                    numbers.push(j / i);
                    break;
                case '^':
                    numbers.push((int)(Math.pow(j, i)));
                    break;
                default:
                    throw new DataFormatException();
            }

        }
    } catch (EmptyStackException e3) {
        operators.push(character);
        continue;
    }

假设相应地定义了getValue()方法:

public int getValue(char character)
throws DataFormatException {
    switch (character) {
        case '+':
            return 1;
        case '-':
            return 1;
        case '*':
            return 2;
        case '/':
            return 2;
        case '^':
            return 3;
        default:
            throw new DataFormatException();
    }

}