/**
* @ClassName SymbolicPriority
* @Description 符号优先级设置
* @Author lzq
* @Date 2018/12/3 12:04
* @Version 1.0
**/
public class SymbolicPriority {
public static final int LEFT_BRACKET = 4; //左括号
public static final int RIGHT_BRACKET = 1; //右括号
public static final int ADD = 2; //加号
public static final int MINUS = 2; //减号
public static final int TIMES = 3; //乘号
public static final int DIVIDE = 3; //除号
public static final int ERROR = -1; //不是任何计算符号
}
import java.util.Arrays;
/**
* @ClassName Stack
* @Description 通用栈
* @Author lzq
* @Date 2018/11/13 15:32
* @Version 1.0
**/
public class Stack {
int top;
T[] elem;
public Stack() {
this(10);
}
public Stack(int number) {
this.elem = (T[])new Object[number];
this.top = 0;
}
/**
* 判空
* @return
*/
public boolean isEmpty() {
return this.top == 0;
}
/**
* 判满
* @return
*/
public boolean isFull() {
return this.top == this.elem.length;
}
/**
* 入栈
* @param val
*/
public void push(T val) {
if(isFull()) {
this.elem = Arrays.copyOf(elem,elem.length*2);
}
this.elem[top++] = val;
}
/**
* 出栈
*/
public void pop() {
if(isEmpty()) {
return;
}
this.top--;
}
/**
* 获得栈顶元素
* @return
*/
public T get_top() {
if(isEmpty()) {
return null;
}
return this.elem[top-1];
}
}
/**
* @ClassName Suffix
* @Description 后缀表达式的四种运算及中缀转后缀
* @Author lzq
* @Date 2018/12/3 12:00
* @Version 1.0
**/
public class Suffix {
/**
* 获取符号的优先级
* @param x
* @return
*/
public int get_priority(char x) {
int priority = 0;
switch (x) {
case '+':
priority = SymbolicPriority.ADD;
break;
case '-':
priority = SymbolicPriority.MINUS;
break;
case '*':
priority = SymbolicPriority.TIMES;
break;
case '/':
priority = SymbolicPriority.DIVIDE;
break;
case '(':
priority = SymbolicPriority.LEFT_BRACKET;
break;
case ')':
priority = SymbolicPriority.RIGHT_BRACKET;
break;
default:
priority = SymbolicPriority.ERROR;
System.out.println("符号错误!");
}
return priority;
}
/**
* 中缀转后缀
* @return
*/
public StringBuilder infix_to_suffix(String string) {
char[] chars = string.toCharArray();
StringBuilder stringBuilder = new StringBuilder();
int i = 0;
Stack stack = new Stack<>();
while (i < chars.length) {
//判断当前字符是不是数字
if (Character.isDigit(chars[i])) {
stringBuilder.append(chars[i]); //如果是数字,直接输出
} else if(get_priority(chars[i]) == -1){ //输入的表达式有非数字和非计算符号
return null;
} else {
/**
* 如果栈是空的,或者入栈的优先级比栈顶元素优先级高,或者栈顶元素是一个左括号
* 直接入栈
*/
if (stack.isEmpty() || (chars[i] != ')' && stack.get_top() == '(')||
get_priority(chars[i]) > get_priority(stack.get_top()) ) {
stack.push(chars[i]);
} else {
//如果当前字符是右括号,那么一直出栈,出到左括号出栈为止
if (chars[i] == ')') {
while (!stack.isEmpty() && stack.get_top() != '(') {
stringBuilder.append(stack.get_top());
stack.pop();
}
if(stack.isEmpty()) {
System.out.println("右括号多了!");
return null;
}else {
//循环出来是栈顶肯定是左括号,不要它了
stack.pop();
}
} else {
//否则的话,当前字符就是计算符号,出栈到优先级比他高的为止
while (!stack.isEmpty() && get_priority(chars[i]) <= get_priority(stack.get_top())) {
if (stack.get_top() == '(') { //碰到左括号就不能出了
break;
}
stringBuilder.append(stack.get_top());
stack.pop();
}
//出完了自己再入栈
stack.push(chars[i]);
}
}
}
i++;
}
//把栈里面的元素全拿出来
while(!stack.isEmpty()) {
if(stack.get_top() == '(') {
System.out.println("左括号多了!");
return null;
}
stringBuilder.append(stack.get_top());
stack.pop();
}
return stringBuilder;
}
/**
* 后缀表达式的计算
* @param string
* @return
*/
public int suffix(String string) {
if(infix_to_suffix(string) == null) {
System.out.println("输入不正确!");
return Integer.MIN_VALUE;
}
String s1 = new String(infix_to_suffix(string)); //首先要拿到后缀表达式
Stack stack = new Stack<>();
int i = 0,temp1,temp2,temp = 0;
while (i < s1.length()) {
if(Character.isDigit(s1.charAt(i))) {
stack.push(Integer.parseInt(String.valueOf(s1.charAt(i))));
}else {
//后缀表达式不可能把计算符号放前面,就不需要判空了
//注意这个有先后顺序的,栈顶的元素作为减数、除数...
temp1 = stack.get_top();
stack.pop();
//出栈一次后,栈顶的元素作为被减数、被除数...
temp2 = stack.get_top();
stack.pop();
temp = operation(s1.charAt(i),temp2,temp1);
stack.push(temp);
}
i++;
}
return temp;
}
/**
* 计算
* @param m
* @param x
* @param y
* @return
*/
public int operation(char m,int x,int y) {
int temp = 0;
switch (m) {
case '+':
temp = x+y;
break;
case '-':
temp = x-y;
break;
case '*':
temp = x*y;
break;
case '/':
temp = x/y;
break;
default:
System.out.println("符号错误!");
break;
}
return temp;
}
}
测试代码:
public static void main(String[] args) {
for(;;) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入中缀表达式:");
String string = scan.nextLine();
Suffix s = new Suffix();
System.out.println(string + "的后缀表达式为:" + s.infix_to_suffix(string));
System.out.println("后缀表达式计算结果为:" + s.suffix(string)+"\n");
}
请输入中缀表达式:
((1+2)*(4-2)-1)*5-(2+2)*(3+3)
((1+2)*(4-2)-1)*5-(2+2)*(3+3)的后缀表达式为:12+42-*1-5*22+33+*-
后缀表达式计算结果为:1
请输入中缀表达式:
2+3*5-4*((5-3)
左括号多了!
2+3*5-4*((5-3)的后缀表达式为:null
左括号多了!
输入不正确!
后缀表达式计算结果为:-2147483648
请输入中缀表达式:
9+(3-1))*3
右括号多了!
9+(3-1))*3的后缀表达式为:null
右括号多了!
输入不正确!
后缀表达式计算结果为:-2147483648
请输入中缀表达式: