博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现四则运算——逆波兰表达式
阅读量:4073 次
发布时间:2019-05-25

本文共 3963 字,大约阅读时间需要 13 分钟。

1.将中缀表达式转化为逆波兰式的思路,如将1+2转化为12+:
 

    定义一个stringbuffer来存放后缀式,并定义一栈stack 

  

Java代码  
  1. loop:读取读取输入的字符串,将当前读入的字符记为a:  
  2.     step1:如果a为操作数则直接append到stringbuffer中.  
  3.    step2:如果a为左括号“(”则将a进栈  
  4.     step3:如果a为右括号,则从栈顶开始找,并移动栈顶指针,如果当前栈顶元素非左括号则将栈顶元素append到stringbuffer中,直到找到第一个左括号,找到后将左括号出栈,并注意不要将左括号放到stringbuffer中.  
  5.    step4:如果a为运算符,则取栈顶元素和a进行比较如果栈顶元素的运算符优先级小于a则将a入栈,否则将栈顶弹出存到stringbuffer中,直到栈顶元素的运算符优先级小于a为址,注左括号和右括号的运算优先级比+-*/都低在这里  
  6. d loop;  

    最后将stringbuffer进行toString并拼上stack中的元素就得到后缀表达式 



2.计算逆波兰式的思路
Java代码  
  1.    
  2. 定义一栈 stack:  
  3.  输入一段后缀表达式如12+:  
  4.  loop:逐个读取字符串中的字符记为b:  
  5.  1.如果a为操作数,则入栈  
  6.  2.如果a为操作符,则弹出栈顶最前进两个数用运算符a进行计算,并将计算结果入栈  
  7.  end loop;  

  3,最后将stack的栈元素输入则为运算结果 


贴上代码: 

首先定义一个简单栈,所有代码中都没有进行异常判断,考虑的是实现过程中,各位看官如果觉得代码垃圾请轻拍: 

栈:
Java代码  
  1. / 自定义栈  
  2. class MyStack<T> {  
  3.     private Entry<T> top = new Entry<T>(nullnull);  
  4.     private int size;  
  5.   
  6.     public MyStack() {  
  7.         top.next = null;  
  8.         top.element = null;  
  9.     }  
  10.   
  11.     // 进栈  
  12.     public MyStack<T> push(T t) {  
  13.         Entry<T> node = new Entry<T>(top.next, t);  
  14.         top.next = node;  
  15.         size++;  
  16.         return this;  
  17.     }  
  18.   
  19.     // 出栈  
  20.     public T pop() {  
  21.         if (size == 0) {  
  22.             return null;  
  23.         }  
  24.         Entry<T> t = top.next;  
  25.         Entry<T> foo = top.next.next;  
  26.         top.next = foo;  
  27.         foo = null;  
  28.         size--;  
  29.         return t.element;  
  30.     }  
  31. //得到栈顶元素  
  32.     public T top() {  
  33.         return top.next.element;  
  34.     }  
  35.   
  36.     public int size() {  
  37.         return size;  
  38.     }  
  39. }  
  40.   
  41. // 元素节点  
  42. class Entry<T> {  
  43.     T element;  
  44.     Entry<T> next;  
  45.   
  46.     Entry(Entry<T> next, T e) {  
  47.         this.element = e;  
  48.         this.next = next;  
  49.     }  
  50. }  

//算法实现类Rpn 

Java代码  
  1. //将用户输入的中缀表达式转化成后缀表式  
  2. //并根据后缀表达式计算结果表明  
  3. public class Rpn {  
  4.   
  5.     //此函数只能处理字符串中的数字全是个位数的情况,如果存在十位以上的则此函数的参数就不能用string了  
  6.     //要改为传入一个栈了,并且只计算整数,其它的float,double需稍作修改  
  7.     public int countRpn(String src) {  
  8.         MyStack<String> stack = new MyStack<String>();  
  9.         for (int i = 0; i < src.length(); i++) {  
  10.             String foo = src.charAt(i) + "";  
  11.             if (!isOperator(foo)) {  
  12.                 stack.push(foo);  
  13.             } else {
    //如果是运算符  
  14.                 // 取栈顶两元素进行计算,并将计算结果放入栈顶  
  15.                 String a = stack.pop();  
  16.                 String b = stack.pop();  
  17.                 int temp = count(b, a, foo);// zhu yi chao zuo shu nei xing  
  18.                 stack.push(temp + "");  
  19.   
  20.             }  
  21.         }  
  22.         return Integer.parseInt(stack.pop());//最后栈顶元素的值就是表达式的值了  
  23.     }  
  24.   
  25.     // 是否为运算符  
  26.     public boolean isOperator(String e) {  
  27.         if (null == e || "".equals(e)) {  
  28.             return false;  
  29.         }  
  30.         return "+".equals(e) || "*".equals(e) || "-".equals(e) || "/".equals(e);  
  31.     }  
  32.   
  33.     // 是否是左括号  
  34.     public boolean isLeft(String s) {  
  35.         return "(".equals(s);  
  36.     }  
  37.    //是否是右括号  
  38.     public boolean isRight(String s) {  
  39.         return ")".equals(s);  
  40.     }  
  41.   
  42.     // 根据运算符(e)计算两个数的值班(a,b)  
  43.     public int count(String a, String b, String e) {  
  44.         int temp1 = Integer.parseInt(a);  
  45.         int temp2 = Integer.parseInt(b);  
  46.         if ("+".equals(e)) {  
  47.             return temp1 + temp2;  
  48.         } else if ("-".equals(e)) {  
  49.             return temp1 - temp2;  
  50.         } else if ("*".equals(e)) {  
  51.             return temp1 * temp2;  
  52.         } else {  
  53.             return temp1 / temp2;  
  54.         }  
  55.     }  
  56.   
  57.     // 将中缀表达式转化为后缀表达式(逆波兰式)  
  58.     public String reverse2Rpn(String src) {  
  59.         MyStack<String> stack = new MyStack<String>();  
  60.         StringBuffer sb = new StringBuffer();  
  61.         for (int i = 0; i < src.length(); i++) {  
  62.             String temp = src.charAt(i) + "";  
  63.             if (!isOperator(temp) && !isRight(temp) && !isLeft(temp)) {  
  64.                 // 操作数,+-直接输出  
  65.                 sb.append(temp);  
  66.             } else if (isOperator(temp)) {  
  67.                 // 如果是操作符  
  68.                 if (stack.size() == 0) {
    // 如果zhan为空则入zhan  
  69.                     stack.push(temp);  
  70.                 } else if ("+".equals(temp) || "-".equals(temp)) {  
  71.                     if (isLeft(stack.top())) {
    //如果栈顶为左括号,则直接入栈  
  72.                         stack.push(temp);//直接将操作符入栈  
  73.                     } else {
    //从栈顶往下找,直到找到当前栈顶的操作符优先级小于等于当前操作符  
  74.                         String top = stack.top();  
  75.                         boolean next = true;  
  76.                         while (("*".equals(top) || "/".equals(top)) && next) {  
  77.                             top = stack.pop();  
  78.                             sb.append(top);// 弹出顶部元素  
  79.                             next = stack.size() == 0 ? false : true;  
  80.                         }  
  81.                        stack.push(temp);//  
  82.                     }  
  83.                       
  84.   
  85.                 } else {
    // 操作符为:"*"或"/" 直接入栈  
  86.                     stack.push(temp);// +-的优先级比任何运算符都高,所以直接入栈  
  87.   
  88.                 }  
  89.             } else if (isLeft(temp)) {
    //如果是左括号直接入栈  
  90.                 stack.push(temp);  
  91.   
  92.             } else if (isRight(temp)) {
    // 如果是右括号,则找到左括号,并将找的过程中的字符全部出栈  
  93.                 String top = stack.pop();  
  94.                 boolean next = true;  
  95.                 while (!isLeft(top) && next) {  
  96.                     sb.append(top);  
  97.                     top = stack.pop();  
  98.                     next = stack.size() == 0 ? false : true;  
  99.                 }  
  100.             }  
  101.         }  
  102.         while (stack.size() > 0) {  
  103.             sb.append(stack.pop());  
  104.         }  
  105.         return sb.toString();  
  106.     }  
  107.   
  108.     public static void main(String[] args) {  
  109.         Rpn rpn = new Rpn();  
  110.         String src = rpn.reverse2Rpn("((1+2)*2)*4)+9*(1+2)");  
  111.         System.out.println("后缀表达式为:"+src);  
  112.         System.out.println("计算结果:"+rpn.countRpn(src));  
  113.     }  
  114.   
  115. }  

转载地址:http://rvuni.baihongyu.com/

你可能感兴趣的文章
新版本的linux如何生成xorg.conf
查看>>
xorg.conf的编写
查看>>
启用SELinux时遇到的问题
查看>>
virbr0 虚拟网卡卸载方法
查看>>
No devices detected. Fatal server error: no screens found
查看>>
新版本的linux如何生成xorg.conf
查看>>
virbr0 虚拟网卡卸载方法
查看>>
Centos 6.0_x86-64 终于成功安装官方显卡驱动
查看>>
Linux基础教程:CentOS卸载KDE桌面
查看>>
db sql montior
查看>>
read humor_campus
查看>>
IBM WebSphere Commerce Analyzer
查看>>
Unix + OS IBM Aix FTP / wu-ftp / proftp
查看>>
my read work
查看>>
db db2 base / instance database tablespace container
查看>>
hd disk / disk raid / disk io / iops / iostat / iowait / iotop / iometer
查看>>
project ASP.NET
查看>>
db db2_monitorTool IBM Rational Performace Tester
查看>>
OS + Unix Aix telnet
查看>>
IBM Lotus
查看>>