zoukankan      html  css  js  c++  java
  • 算数表达式求值(中缀表达式转后缀表达式并求值)

    中缀表达式转后缀表达式的规则:
    1.遇到操作数:直接输出(添加到后缀表达式中)
    2.栈为空时,遇到运算符,直接入栈
    3.遇到左括号:将其入栈
    4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
    5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时栈顶的运算符为"(",则将这个运算符也压入栈中)
    6.最终将栈中的元素依次出栈,输出

    具体代码实现:

    第一步:中缀表达式转后缀表达式

      1 package data.struct.algorithm;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.InputStreamReader;
      6 
      7 //定义栈,用于存放转换过程中的操作符
      8 class StackFix {
      9     // 栈的大小
     10     private int maxSize;
     11     // 数组模拟栈
     12     private char stackArr[];
     13     // 栈顶指针
     14     private int top;
     15 
     16     // 构造函数初始化栈
     17     public StackFix(int s) {
     18         maxSize = s;
     19         stackArr = new char[maxSize];
     20         top = -1;
     21     }
     22 
     23     // 进栈
     24     public void push(char value) {
     25         stackArr[++top] = value;
     26     }
     27 
     28     // 出栈
     29     public char pop() {
     30         return stackArr[top--];
     31     }
     32 
     33     // 显示栈顶元素
     34     public char peek() {
     35         return stackArr[top];
     36     }
     37 
     38     // 判断栈是否为空
     39     public boolean isEmpty() {
     40         return top == -1;
     41     }
     42 }
     43 
     44 // 转换类
     45 class InTranstoPost {
     46     private StackFix theStackFix;
     47     private String input;
     48     private String output = "";
     49 
     50     // 初始化
     51     public InTranstoPost(String in) {
     52         input = in;
     53         int stackSize = input.length();
     54         theStackFix = new StackFix(stackSize);
     55     }
     56 
     57     // 主要转换功能函数
     58     public String doTran() {
     59         for (int j = 0; j < input.length(); j++) {
     60             // 获取一个输入字符串的一个字符
     61             char ch = input.charAt(j);
     62             switch (ch) {
     63 
     64             case '+':
     65             case '-':
     66                 // 如果字符为'+'或者'-',若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数1为运算符的优先级
     67                 gotOper(ch, 1);
     68                 break;
     69             case '*':
     70             case '/':
     71                 // 如果字符为'*'或者'/',若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数2为运算符的优先级
     72                 gotOper(ch, 2);
     73                 break;
     74             case '(':
     75                 // 如果字符为'(',则压入栈中
     76                 theStackFix.push(ch);
     77                 break;
     78             case ')':
     79                 // 如果字符为')',则弹出栈顶元素,如果栈顶元素为'(',则结束循环,输出转换结果,否则依次弹出栈顶元素并输出,
     80                 // 直到碰到'('
     81                 gotRbracket(ch);
     82                 break;
     83             default:
     84                 // 字符为操作数,不入栈,直接输出
     85                 output = output + ch;
     86                 break;
     87             }
     88         }
     89         // 判断输入的字符串的每一个字符的循环结束,依次弹出栈中的元素,并输出
     90         while (!theStackFix.isEmpty()) {
     91             output = output + theStackFix.pop();
     92         }
     93         return output;
     94     }
     95 
     96     // 该函数用于字符为')'时的相应操作
     97     public void gotRbracket(char ch) {
     98         while (!theStackFix.isEmpty()) {
     99             char chx = theStackFix.pop();
    100             if (chx == '(') {
    101                 break;
    102             } else {
    103                 output = output + chx;
    104             }
    105         }
    106     }
    107 
    108     // 非')'字符的其他操作符的处理
    109     public void gotOper(char opThis, int prec1) {
    110         while (!theStackFix.isEmpty()) {
    111             char opTop = theStackFix.pop();
    112             if (opTop == '(') {
    113                 theStackFix.push(opTop);
    114                 break;
    115             } else {
    116                 int prec2;
    117                 if (opTop == '+' || opTop == '-') {
    118                     prec2 = 1;
    119                 } else {
    120                     prec2 = 2;
    121                 }
    122                 if (prec2 < prec1) {
    123                     theStackFix.push(opTop);
    124                     break;
    125                 } else {
    126                     output = output + opTop;
    127                 }
    128             }
    129         }
    130         // 栈空,字符直接压入栈中
    131         theStackFix.push(opThis);
    132     }
    133 }
    134 
    135 // 主函数
    136 public class InfixToPostFix {
    137 
    138     /**
    139      * @param args
    140      * @throws IOException
    141      */
    142     public static void main(String[] args) throws IOException {
    143 
    144         // 定义两个字符串,一个接收键盘输入,一个用于代表转换后的字符串
    145         String input, output;
    146         while (true) {
    147             System.out.println("Enter a InFix:");
    148             System.out.flush();
    149             // getString()函数,从键盘获取输入的中缀表达式字符串
    150             input = getString();
    151             // 输入的字符串为空,结束判断
    152             if (input.equals("")) {
    153                 break;
    154             }
    155             // 进行转换
    156             InTranstoPost tran = new InTranstoPost(input);
    157             output = tran.doTran();
    158             System.out.println("Thr Postfix is " + output);
    159         }
    160     }
    161 
    162     // 键盘获取输入的方式,常用做法
    163     public static String getString() throws IOException {
    164         InputStreamReader isr = new InputStreamReader(System.in);
    165         BufferedReader bufr = new BufferedReader(isr);
    166         String s = bufr.readLine();
    167         return s;
    168     }
    169 }

     第二步:后缀表达式求值

    在这里,我的程序没有使用上一步获取的转换后的字符串,而是继续接收用户额输入,如果使用上一步的结果,则程序会变得更简单一些

    求值的步骤:

    (1)设置一个栈,开始时,栈为空,然后从左到右扫描后缀表达式

    (2)若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈

    (3)直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果,弹出栈即可得到结果。

    具体代码实现:

      1 package data.struct.algorithm;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.InputStreamReader;
      6 
      7 class Stackfix2 {
      8     private int maxSize;
      9     private int stackArr[];
     10     private int top;
     11 
     12     public Stackfix2(int maxSize) {
     13         this.maxSize = maxSize;
     14         stackArr = new int[maxSize];
     15         top = -1;
     16     }
     17 
     18     // 进栈
     19     public void push(int value) {
     20         stackArr[++top] = value;
     21     }
     22 
     23     // 出栈
     24     public int pop() {
     25         return stackArr[top--];
     26     }
     27 
     28     // 显示栈顶元素
     29     public int peek() {
     30         return stackArr[top];
     31     }
     32 
     33     // 判断栈是否为空
     34     public boolean isEmpty() {
     35         return top == -1;
     36     }
     37 
     38     public boolean isFull() {
     39         return top == maxSize - 1;
     40     }
     41 }
     42 
     43 class Postfix {
     44     private Stackfix2 theStackfix2;
     45     private String input;
     46 
     47     public Postfix(String in) {
     48         input = in;
     49     }
     50 
     51     public int doCalculate() {
     52         int num1;
     53         int num2;
     54         int inresult;
     55         char ch;
     56         int j;
     57         theStackfix2 = new Stackfix2(20);
     58         for (j = 0; j < input.length(); j++) {
     59             ch = input.charAt(j);
     60             // 如果字符为整数,则进行类型强制转换,并压入栈中
     61             if (ch >= '0' && ch <= '9') {
     62                 theStackfix2.push((int) (ch - '0'));
     63             } else {
     64                 // 测试用例最最关键的位置,考虑计算过程中的操作数的位置
     65                 // 先弹出栈的元素是第二个操作数,后弹出栈的是第一个操作数
     66                 num2 = theStackfix2.pop();
     67                 num1 = theStackfix2.pop();
     68                 switch (ch) {
     69                 case '+':
     70                     inresult = num1 + num2;
     71                     break;
     72                 case '-':
     73                     inresult = num1 - num2;
     74                     break;
     75                 case '*':
     76                     inresult = num1 * num2;
     77                     break;
     78                 case '/':
     79                     inresult = num1 / num2;
     80                     break;
     81                 default:
     82                     inresult = 0;
     83                     break;
     84                 }
     85                 theStackfix2.push(inresult);
     86             }
     87         }
     88         return theStackfix2.pop();
     89     }
     90 }
     91 
     92 public class PostfixValue {
     93 
     94     /**
     95      * @param args
     96      * @throws IOException
     97      */
     98     public static void main(String[] args) throws IOException {
     99 
    100         while (true) {
    101             System.out.println("Enter a Postfix:");
    102             System.out.flush();
    103             String input;
    104             int result;
    105             input = getString();
    106             Postfix parse = new Postfix(input);
    107             result = parse.doCalculate();
    108             System.out.println("Postfix求值的结果是:" + result);
    109         }
    110     }
    111 
    112     public static String getString() throws IOException {
    113         InputStreamReader isr = new InputStreamReader(System.in);
    114         BufferedReader bufr = new BufferedReader(isr);
    115         return bufr.readLine();
    116     }
    117 
    118 }
  • 相关阅读:
    vue 倒计时返回首页
    vue2借助animate.css实现路由动画效果
    CSS3实现文本垂直排列
    button在点击时出现边框
    vue项目中设置背景图片
    Python -处理PDF
    Python学习笔记(1)-列表
    转:Redis 的安装配置介绍
    转:windows xp下如何安装SQL server2000企业版
    转:CodeCube提供可共享、可运行的代码示例
  • 原文地址:https://www.cnblogs.com/ysw-go/p/5374341.html
Copyright © 2011-2022 走看看