二叉樹解析實現逆波蘭公式演算法

來源:互聯網
上載者:User

public class NiBoLan {
 private static final int MAX_NODE = 100;

 // 二叉樹的結點類
 private static class MyTreeNode {
  public double value;// 若結點是數字,則儲存為該結點的值;若是符號,則此欄位無意義
  public char symbol;// '+','-','*','/','d'
  public int left;// 左孩子
  public int right;// 右孩子
  public int father;// 爹地

  public void init() {
   value = 0;
   symbol = '\0';
   left = -1;
   right = -1;
   father = -1;
  }
 }

 private static boolean isOperator(char c) {
  if (c == '+' || c == '-' || c == '*' || c == '/') {
   return true;
  }
  return false;
 }

 private static boolean isDigit(char c) {
  if ((c <= '9' && c >= '0') || c == '.') {
   return true;
  }
  return false;
 }

 // 用遞迴計算樹的值
 private static double getNodeValue(MyTreeNode[] tree, int nodeNum)
   throws Exception {
  // 如果結點是數字,直接傳回值
  if (tree[nodeNum].symbol == 'd') {
   return tree[nodeNum].value;
  }
  // 如果結點是符號,則遞迴計算
  if (tree[nodeNum].symbol == '+') {
   return getNodeValue(tree, tree[nodeNum].left)
     + getNodeValue(tree, tree[nodeNum].right);
  }
  if (tree[nodeNum].symbol == '-') {
   return getNodeValue(tree, tree[nodeNum].left)
     - getNodeValue(tree, tree[nodeNum].right);
  }
  if (tree[nodeNum].symbol == '*') {
   return getNodeValue(tree, tree[nodeNum].left)
     * getNodeValue(tree, tree[nodeNum].right);
  }
  if (tree[nodeNum].symbol == '/') {
   return getNodeValue(tree, tree[nodeNum].left)
     / getNodeValue(tree, tree[nodeNum].right);
  }
  throw new Exception("tree error");
 }

 // 計算逆波蘭運算式
 public static double calculate(String str) {
  double result = 0;
  MyTreeNode tree[] = new MyTreeNode[MAX_NODE];
  for (int i = 0; i < MAX_NODE; i++) {
   tree[i] = new MyTreeNode();
   tree[i].init();
  }
  int nowCount = 0;
  int pointerTmp = -1;

  try {
   // 建立整棵二叉樹
   // 注意,逆波蘭式解析起來應該是從右向左
   for (int i = str.length() - 1; i >= 0; i--) {
    if (isOperator(str.charAt(i)) || isDigit(str.charAt(i))) {
     // 若是符號
     if (isOperator(str.charAt(i))) {
      tree[nowCount].symbol = str.charAt(i);
     }
     // 若是數字
     else if (isDigit(str.charAt(i))) {
      int numEnd = i;
      while (isDigit(str.charAt(i))) {
       i--;
       if (i < 0) {
        break;
       }
      }
      i++;
      tree[nowCount].value = Double.valueOf(str.substring(i,
        numEnd + 1));
      tree[nowCount].symbol = 'd';
     }

     // 現在開始的代碼為核心+關鍵
     // 向上找到父結點,掛載當前結點,構建二叉樹
     pointerTmp = nowCount - 1;
     while (pointerTmp >= 0) {
      // 因為數字一定在葉子結點上,因此忽略數字結點
      // 優先查看找到的非葉子的右孩子,如果為空白,就認其為父
      if (tree[pointerTmp].right < 0
        && tree[pointerTmp].symbol != 'd') {
       tree[pointerTmp].right = nowCount;
       tree[nowCount].father = pointerTmp;
       break;
      }
      // 如果右孩子非空,就看左孩子,如果為空白,就認賊作父
      if (tree[pointerTmp].left < 0
        && tree[pointerTmp].symbol != 'd') {
       tree[pointerTmp].left = nowCount;
       tree[nowCount].father = pointerTmp;
       break;
      }
      // 如果都不為空白,繼續向上尋找。"我要我要找我爸爸,去到哪裡也要找我爸爸~~~"
      pointerTmp = tree[pointerTmp].father;
     }
     // 如果找不到爹地,哼哼,那怎麼可能!難道是無性繁殖?
     if (nowCount != 0 && pointerTmp < 0) {
      throw new Exception("我靠,你就不能寫個正確的運算式阿");
     }
     nowCount++;
    }
   }
   // 計算結果
   result = getNodeValue(tree, 0);
  } catch (Exception e) {
   // 如果運算式錯誤,輸出提示
   System.out.println("The next expression error!");
   result = 0;
  }

  return result;
 }

 public static void main(String[] args) {

  String str = "1 2 3 4 5*-6 + -*";
  String str2 = "1.23 252.6 3 4.8 5* - * 6 + *";
  String str3 = "1.23 252.6 3 4.8 5* - * 6 ++ *";// 這個運算式是錯的,輸出錯誤提示
  String str4 = "1.23 252.6 3 4.8 5";// 這個運算式還是錯的,輸出錯誤提示
  System.out.println(str + " = " + calculate(str));
  System.out.println(str2 + " = " + calculate(str2));
  System.out.println(str3 + " = " + calculate(str3));
  System.out.println(str4 + " = " + calculate(str4));
 }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.