zoukankan      html  css  js  c++  java
  • 逆波兰表达式(RPN)算法简单实现

    一、预处理

    给定任意四则运算的字符串表达式(中缀表达式),preDeal预先转化为对应的字符串数组,其目的在于将操作数和运算符分离。

    例如给定四则运算内的中缀表达式:

    String infix = "100+8*5-(10/2)*5+10.5";

    字符串数组化后得:

    {"100","+","8","*","5","-","(","10","/","2",")","+","10.5"}

    二、中缀表达式转后缀表达式

    规则:

    遍历中缀表达式,

    A、如果遇到操作数直接输出

    B、如果遇到运算符,分情况:

    B1:如果是*、/或者(这三个运算符,直接压栈

    B2:如果是),则出栈直到遇到(位置。(左括号和有括号并不参与拼接后缀表达式)。

    B3:如果是+或者-,先弹栈直到栈空,再讲当前的+或者-压栈。

    其中情况B可以总结:

    遇到右括号出栈直到匹配左括号,遇到操作符,如果其优先级高于栈顶元素,则继续压栈,否则出栈。

    三、计算后缀表达式

    规则:

    遍历后缀表达式:

    A、遇到操作数压栈

    B、遇到运算符则将栈顶和次栈顶两个元素取出参与对应的运算,再将运算结结果压栈。

    四、Java算法实现

      1 package agstring;
      2 import java.util.*;
      3 
      4 
      5 public class RPN {
      6     public static String[] preDeal(String infix){
      7         infix = infix.trim();
      8         int length = infix.length();
      9         ArrayList<String> infixOfArrayList = new ArrayList<String>();
     10         char currChar;
     11         int index = 0;
     12         final String regex = "\+|-|\*|\/|\(|\)";
     13         for (int i = 0; i < length; i++) {
     14             currChar = infix.charAt(i);
     15             if(String.valueOf(currChar).matches(regex)){//运算符
     16                 if (index < i) {
     17                     infixOfArrayList.add(infix.substring(index,i));//add数字
     18                 }
     19                 infixOfArrayList.add(String.valueOf(currChar));
     20                 index = i+1;
     21             }
     22         }
     23         infixOfArrayList.add(infix.substring(index,length));
     24         return infixOfArrayList.toArray(new String[infixOfArrayList.size()]);
     25     }
     26     public static String[]  getPostfix(String infix) {
     27         String[] infixOfAry = preDeal(infix);
     28         int length = infixOfAry.length;
     29         ArrayDeque<String> stack = new ArrayDeque<String>();
     30         String currString = "";
     31         final String regex = "\+|-|\*|\/|\(|\)";
     32         ArrayList<String> postfixOfArrayList = new ArrayList<String>();
     33         for (int i = 0; i < length; i++) {
     34             currString = infixOfAry[i];
     35             if (currString.matches(regex)) {//symbol
     36                 if (currString.matches("\*|\/|\(")) {
     37                     stack.offerFirst(currString);
     38                 }else {//),+,-
     39                     String top = "";
     40                     if(currString.equals(")")){
     41                         while(!stack.isEmpty()){
     42                             top = stack.removeFirst();
     43                             if (top.equals("(")) {
     44                                 break;
     45                             }
     46                             postfixOfArrayList.add(top);
     47                         }
     48                     }else {//+ ,-
     49                         if (!stack.isEmpty()) {
     50                             top = stack.peekFirst();
     51                             if (top.equals("*") || top.equals("/")) {
     52                                 while(!stack.isEmpty()){
     53                                     postfixOfArrayList.add(stack.removeFirst());
     54                                 }
     55                             }
     56                         }
     57                         stack.offerFirst(currString);
     58                     }
     59                 }
     60             }else {//number
     61                 postfixOfArrayList.add(currString);
     62             }
     63         }
     64         while(!stack.isEmpty()){
     65             postfixOfArrayList.add(stack.removeFirst());
     66         }
     67         return postfixOfArrayList.toArray(new String[postfixOfArrayList.size()]);
     68     }
     69     public static double computePostfix(String infix){
     70         String[] postfixAry = getPostfix(infix);
     71         ArrayDeque<Double> stack = new ArrayDeque<Double>();
     72         int length = postfixAry.length;
     73         String currString = "";
     74         final String regex = "\+|-|\*|\/|\(|\)";
     75         double operandOne,operandTwo;
     76         for (int i = 0; i < length; i++) {
     77             currString = postfixAry[i];
     78             if (currString.matches(regex)) {
     79                 operandOne = stack.removeFirst();
     80                 operandTwo = stack.removeFirst();
     81                 switch (currString.charAt(0)) {
     82                 case '+':
     83                     stack.addFirst(operandTwo + operandOne);
     84                     break;
     85                 case '-':
     86                     stack.addFirst(operandTwo - operandOne);
     87                     break;
     88                 case '*':
     89                     stack.addFirst(operandTwo * operandOne);
     90                     break;
     91                 case '/':
     92                     stack.addFirst(operandTwo / operandOne);
     93                     break;
     94                 }
     95                 
     96             }else {
     97                 stack.addFirst(Double.parseDouble(currString));
     98             }
     99         }
    100         return stack.removeFirst();
    101     }
    102     public static void main(String[] args) {
    103         // TODO Auto-generated method stub
    104         try {
    105             String infix = "100+8*5-(10/2)*5+10.5";
    106             double result = computePostfix(infix);
    107             System.out.println(result);    
    108         } catch (Exception e) {
    109             // TODO: handle exception
    110             e.printStackTrace();
    111         }
    112     }
    113 
    114 }

     (完)

    转载请注明原文出处:http://www.cnblogs.com/qcblog/p/7502666.html

  • 相关阅读:
    Audacious 1.3.0
    medit-多平台的 GTK 文本编辑器
    PIDA:基于 Gtk 的 Python IDE
    Xfce 4.4.0 for Ubuntu Edgy Eft
    Lemonrip-DVD 提取对象
    Tomboy 0.5.5
    网管经验谈:成功网管必备素质硬件篇
    再学 GDI+[35]: TGPPen 虚线画笔位移 SetDashOffset
    再学 GDI+[33]: TGPPen 画笔的几何变换 SetTransform
    再学 GDI+[37]: TGPPen TGPCustomLineCap、SetCustomStartCap、SetCustomEndCap
  • 原文地址:https://www.cnblogs.com/qcblog/p/7502666.html
Copyright © 2011-2022 走看看