算数表达式求值(中缀表达式转后缀表达式并求值)

中缀表达式转后缀表达式的规则:
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 }

 

posted @ 2016-04-10 15:57  菜鸟奋斗史  阅读(1167)  评论(0编辑  收藏  举报