第八周(11.04-11.10)----结对项目----逆波兰

基本概念

  逆波兰式(ReversePolishnotation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)。

  中序表达式就是我们数学中常见的算式形式。

举例说明

  中序表达式:3+4*5-6

  转化成逆波兰式:3 4 5 * + 6 -

算法思想

  首先建立两个栈,一个数据栈OPDN,一个操作符栈OPTR。

  先将“#”栈底标志放到操作符栈。

  从中序表达式pre的第一个字符读起:

    1.如果pre[i]是操作数,就直接入数据栈;

    2.如果pre[i]为左括号,就压入操作符栈;

    3.如果pre[i]为右括号,就将操作符栈中的运算符一次出栈并依次压入数据栈,一直到操作符栈顶元素为左括号停止,但是这个时候要将左括号出栈,而且不压入数据栈;

    4.如果pre[i]为操作符:

      a.如果操作符栈为空,就将操作符pre[i]压入数据栈;

      b.如果pre[i]的优先级大于操作符栈顶元素的优先级,就将此pre[i]压入数据栈;

      c.如果操作符栈不为空而且pre[i]的优先级小于等于操作符栈顶元素的优先级,就将操作符栈中的元素依次出栈并且压入数据栈,指导不满足上述条件,将此操作符pre[i]压入数据栈。

    5.如果遍历完整个中序的表达式,操作符栈还存有运算符,就将全部运算符出栈并且压入数据栈,直到为空。

    6.最后将整个数据栈的元素依次压入操作符栈,然后正序输出操作符栈就可以得到逆波兰式了。

利用栈将中序表达式转换成逆波兰式代码表达

建立computer类和Mycounter主类

class computer

类方法 说明
public int randomnum() 返回一个随机数
public String symbol() 返回+-*/中的一个随机符号
public boolean isNum(String pre) 判断中序表达式中的字符是否为数字
public boolean isoperator(String sym) 判断中序表达式中的字符是否为“+,-,*,/”符号中的一种
public int priority(String sym) 返回每种符号的优先级表示数
void toback(String pre[]) 将输入的pre[]转换成逆波兰式后输出

 

 

 

 

 

 

 

  1 package Mycounter;
  2 import java.lang.Math;
  3 import java.util.Stack;
  4 import java.util.regex.Matcher;
  5 import java.util.regex.Pattern;
  6 public class computer {
  7     //生成0-100的随机数
  8     public int randomnum() {
  9         int random = (int)(Math.random()*10);//Math.random的范围是[0.0-1.0]
 10         return random;
 11         
 12     }
 13     //生成一个随机符号
 14     public String symbol(){
 15         
 16         int i=0;
 17         switch(i=(int) (Math.random() * 4))
 18         {
 19         case 0:
 20             return "+";
 21         case 1:
 22             return "-";
 23         case 2:
 24             return "*";
 25         case 3:
 26             return "/";
 27         default :
 28             return null;
 29         }
 30 
 31     }
 32     //判断是否为数字
 33     public boolean isNum(String pre){ 
 34            Pattern pattern = Pattern.compile("[0-9]*"); //通过正则表达式判断String类型是否为数字
 35            Matcher isNum = pattern.matcher(pre);
 36            if( !isNum.matches() ){
 37                return false; 
 38            } 
 39            return true; 
 40         }
 41     //判断时否为符号
 42     public boolean isoperator(String sym){
 43         switch(sym)
 44         {
 45         case "+":
 46             return true;
 47         case "-":
 48             return true;
 49         case "*":
 50             return true;
 51         case "/":
 52             return true;
 53         default :
 54             return false;
 55         }
 56     }
 57     //判断符号优先级,#为栈底标志
 58     public int priority(String sym){
 59         switch(sym)
 60         {
 61         case "#":
 62             return -1;
 63         case "(":
 64             return 0;
 65         case "+":
 66             return 1;
 67         case "-":
 68             return 1;
 69         case "*":
 70             return 2;
 71         case "/":
 72             return 2;
 73         default :
 74             return -1;
 75         }
 76     }
 77     //中缀表达式转化前缀表达式
 78     void toback(String pre[]){
 79         
 80         String bottom="#";
 81         Stack<String> OPTR = new Stack();   //运算符栈
 82         Stack<String> OPND = new Stack();   //数据栈
 83         
 84         OPTR.push(bottom);    // 首先把结束标志‘#’放入栈底
 85         
 86         for(int k=0;k<pre.length;k++)
 87         {
 88             if(isNum(pre[k])) // 遇到数直接写入后缀表达式
 89             {
 90                 OPND.push(pre[k]);
 91             }
 92             else if (pre[k]=="(")    // 遇到“(”不用比较直接入栈
 93                 OPTR.push(pre[k]);
 94             else if(pre[k] ==")")  // 遇到右括号将其对应左括号后的操作符(操作符栈中的)全部写入后缀表达式
 95             {
 96                 while(OPTR.peek()!="(")
 97                 {
 98                     OPND.push( OPTR.peek());
 99                     OPTR.pop();
100                 }
101                 OPTR.pop(); // 将“(”出栈,后缀表达式中不含小括号
102             }
103             else if (isoperator(pre[k]))
104             {
105                  while(!OPTR.empty() && priority(pre[k]) <= priority(OPTR.peek()))
106                  {
107                      // 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程
108                      OPND.push(OPTR.peek());
109                      OPTR.pop();
110                  }
111                  OPTR.push(pre[k]);// 当前操作符栈为空或者当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈
112             }
113                        
114         }
115         while(OPTR.peek() != "#") // 将所有的操作符加入后缀表达式
116         {
117             OPND.push(OPTR.peek());
118             OPTR.pop();
119         }
120         OPTR.pop();
121 
122         //利用操作符栈逆序即可得到后缀表达式
123         while(!OPND.empty())
124         {
125             OPTR.push(OPND.peek());
126             OPND.pop();
127         }
128         while(!OPTR.empty())
129         {
130             System.out.print(OPTR.peek()+" ");
131             OPTR.pop();
132         }
133 
134     }
135 }

Mycounter

主类控制

 1 package Mycounter;
 2 
 3 import java.util.Scanner;
 4 
 5 import Mycounter.computer;
 6 public class Mycounter {
 7 
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10         computer yl = new computer();
11         int y1=yl.randomnum();//随机数y1,y2,y3,y4
12         int y2=yl.randomnum();
13         int y3=yl.randomnum();
14         int y4=yl.randomnum();
15         String sym1=yl.symbol();//随机操作符sym1,sym2,sym3
16         String sym2=yl.symbol();
17         String sym3=yl.symbol();
18         
19         String[] zhongshi={String.valueOf(y1),sym1,String.valueOf(y2),sym2,String.valueOf(y3),sym3,String.valueOf(y4)} ;//按中序表达式顺序存入String[]
20         for(int i=0;i<zhongshi.length;i++){            //输出中序表达式
21             System.out.print(zhongshi[i]);
22             
23         }
24         System.out.println("");
25         yl.toback(zhongshi);                    //转换成逆波兰式
26     }
27 
28 }

鸣谢

感谢http://blog.csdn.net/axiqia/article/details/50538878#逆波兰表达式中序表达式转后序表式式 博主的写出这么详尽的算法解读和代码演示

代码

https:https://git.coding.net/YangXiaomoo/fourcount.git

ssh:git@git.coding.net:YangXiaomoo/fourcount.git

git:git://git.coding.net/YangXiaomoo/fourcount.git

 

posted @ 2016-11-09 22:06  YangXiaomoo  阅读(233)  评论(1编辑  收藏  举报