2014-11-05 168 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(); 
    } 

}