2014-11-05 163 views
0

我正在编写验证算术表达式的程序是否正确形成。 (例如:正确的形式"2 + (2-1)",不正确的形式")2+(2-1"获取Java程序以读取括号,括号和大括号

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

目前,它可以很容易地计算括号中的任何内容。但是如果涉及到括号(例如,"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。起初,我认为最合适的解决方案就是将这两种方法包含在parentheses中。像这样:(但它仍然在读的括号罚款)

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

您的示例“2 [3 +(1)]”不包含大括号,只包含圆括号和方括号。你的意思是使用方括号吗?此外,嵌套的括号只能嵌套在方括号中的圆括号中,还是方括号可以嵌套在圆括号内? – Bohemian 2014-11-05 21:58:20

+0

“但无法计算结果”程序是否计算出错误或者是否有异常?你检查了2(3 +(1))是否在工作吗? – Turing85 2014-11-05 21:59:11

+0

您是否尝试过使用调试器,或者在代码中放置一些'println'或其他东西来验证变量是您认为它们应该是的还是这些方法正在返回您认为它们应该返回的内容? – ajb 2014-11-05 22:01:49

回答

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(); 
    } 

}