//将一个算术表达式转化成为逆波兰式
package com.snow.ee;
import java.util.Stack;
public class TestNibolanshi {
String expression ="(1*5-12*(3+5))/7+5";
public static void main(String[] args) {
TestNibolanshi test= new TestNibolanshi();
test.nibolanshi();
}
//判断是否为数字
public static boolean isDigit(char c){
if(c>=‘0‘&&c<=‘9‘){
return true;
}
return false;
}
//判断是否是操作符
public static boolean isOperator(char c){
if(c==‘+‘||c==‘-‘||c==‘*‘||c==‘/‘||c==‘(‘||c==‘)‘){
return true;
}
return false;
}
//计算
public static double simpleCal(double leftNum, char c, double rightNum) {
switch (c) {
case ‘+‘:
return leftNum + rightNum;
case ‘-‘:
return leftNum - rightNum;
case ‘*‘:
return leftNum * rightNum;
case ‘/‘:
return leftNum / rightNum;
default:
throw new RuntimeException();
}
}
//优先级比较: 1表示>,0表示=,-1表示<,9表示无法比较
//优先级高的先计算
char [] c = {‘+‘,‘-‘,‘*‘,‘/‘,‘(‘,‘)‘,‘#‘};
int[][] youxianji={ /* + */ { 1, 1, -1, -1, -1, 1, 1},
/* - */ { 1, 1, -1, -1, -1, 1, 1},
/* * */ { 1, 1, 1, 1, -1, 1, 1},
/* / */ { 1, 1, 1, 1, -1, 1, 1},
/* ( */ {-1, -1, -1, -1, -1, 0, 9},
/* ) */ { 1, 1, 1, 1, 9, 1, 1},
/* # */ {-1, -1, -1, -1, -1, 9, 0}
};
//假设计算的数据都为整数int
public int youxianji(char c1,char c2){
int m = 0,n = 0;
for(int i=0;i<c.length;i++){
if(c[i]==c1){
m=i;
break;
}
}
for(int i=0;i<c.length;i++){
if(c[i]==c2){
n=i;
break;
}
}
return youxianji[m][n];
}
//将一个表达式变为逆波兰式
public void nibolanshi(){
Stack<String> result = new Stack<>();//结果
Stack<Character> operator = new Stack<>();//存放运算符
operator.push(‘#‘);
char[] arr = expression.toCharArray();
int arrlen = 0;//表示目前扫描到arr数组的第arrlen个
StringBuffer tempVar = new StringBuffer();//存放临时变量
while(arrlen<arr.length){
if(Test01.isDigit(arr[arrlen])){//1、若arr[arrlen]为操作数,则分析出完整的操作数,然后压入result栈顶
do{
tempVar.append(arr[arrlen]);
arrlen++;
}while(arrlen<arr.length && Test01.isDigit(arr[arrlen]));//此处应先判断arrlen<arr.length
result.push(tempVar.toString());
tempVar.setLength(0);
} else if(arrlen<arr.length && Test01.isOperator(arr[arrlen]) ){//2、若arr[arrlen]为操作符:
// 1表示>,0表示=,-1表示<,9表示无法比较;
//如果 < 即yxj=-1,直接放到operator中
//如果 > j即yxj=1,将operator的栈顶元素放入result 中,直到 yxj=-1
int yxj = this.youxianji(operator.peek(), arr[arrlen]);//计算操作符优先级
if(yxj==-1){ //若operator 栈的栈顶操作符的优先级 > arr[arrlen] 的优先级,直接压入operator栈
operator.push(arr[arrlen]);
}else if(yxj==1){//若operator操作符栈顶元素的符号的优先级 > arr[arrlen]时:
do{ //先将operator栈中所有优先级 > arr[arrlen]的操作符压入result栈,
//直到operator栈顶元素优先级 < 或 = arr[arrlen]
result.push(operator.pop().toString());
}while(youxianji(operator.peek(), arr[arrlen])==1);
//然后判断operator栈顶操作符优先级到底是< 还是 = arr[arrlen]
//若 < 直接压入operator栈顶
if(youxianji(operator.peek(), arr[arrlen])==-1){
operator.push(arr[arrlen]);
} else if(youxianji(operator.peek(), arr[arrlen])==0){//若 = 将operator 栈顶操作符去除
operator.pop();
}
}else if(yxj==0){//3、若operator操作符栈顶元素的符号的优先级 = arr[arrlen]时:
//直接将operator 栈顶操作符去除
operator.pop();
}
//然后判断下一个操作符
arrlen++;
}
}
while(!operator.isEmpty() && operator.peek()!=‘#‘){
result.push(operator.pop().toString());
}
for(String s:result){
System.out.print(s+" ");
}
}
}
//注意:转换为逆波兰式的算法的关键在于比较操作符之间的优先级
原文:http://www.cnblogs.com/snowcoming/p/6412802.html