zoukankan      html  css  js  c++  java
  • 第八周(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

  • 相关阅读:
    在Fiddler中捕获IIS / ASP.NET流量
    SQL Server 索引分析开关
    解决谷歌浏览器在F12情况下自动断点问题(Paused in debugger)
    SQL Server 移位运算符
    手动更新了packages.config Nuget配置文件,自动引用dll
    转载:如何严格限制session在30分钟后过期!
    Sphinx 2.0.8 发布,全文搜索引擎 Installing Sphinx on Windows
    Where does Oracle SQL Developer store connections? oracle SQL Developer 连接信息保存的位置,什么地方
    利用 ROW_NUMBER() OVER ( ORDER BY 进行选择性排序,按不同字段进行排序处理,分页
    大数据学习网站
  • 原文地址:https://www.cnblogs.com/YangXiaomoo/p/6049001.html
Copyright © 2011-2022 走看看