import java.util.*;
/**
* @auther sofency
* @date 2020/2/13 14:50
* @package 韩顺平数据结构
* 逆波兰表达式 将中缀表达式转化为后缀表达式 然后再进行运算
*/
public class PolandNotation {
//将中缀表达式转化为List
public static List<String> toInfixExpressionList(String s){
//定义一个List 存放 中缀表达式对应的内容
int i=0;//这是一个指针 用于遍历 中缀表达式字符串
String str;//对多位数的拼接
char c;//每遍历一个字符就放入到c
List<String> list = new ArrayList<>();
do{
if((c=s.charAt(i)) < 48 || (c=s.charAt(i)) > 57){//说明不是数字
list.add(c+"");
i++;
}else{
str = "";
while(i<s.length()&& (c=s.charAt(i))>=48&& (c=s.charAt(i)) <= 57){
str+=c;
i++;
}
list.add(str);
}
}while(i<s.length());
return list;
}
public static Integer getProperity(String str){
Map<String,Integer> map = new HashMap<>();
map.put("+",1);
map.put("-",1);
map.put("*",2);
map.put("/",2);
map.put("(",3);
map.put(")",3);
return map.get(str);
}
//list集合的中缀表达式转化为后缀表达式
public static List<String> changePoly(List<String> list){
Stack<String> stack = new Stack();//存储非数字的字符
List<String> opera = new ArrayList<>();//存储逆波兰表达式
for(String str : list){
if(str.matches("\\d+")){//是数字
opera.add(str);
}else if (str.equals("(")){//匹配到左括号
stack.push(str);//入符号栈
}else if(str.equals(")")){//匹配到右括号
//符号出栈 直到遇到(
while(!stack.peek().equals("(")){//将括号里面的字符弹栈添加到逆波兰字符串列表中
opera.add(stack.pop());
}
stack.pop();//弹出(
}else{//比较优先级的问题
//如果当前元素的优先级大于栈顶元素的优先级的话那么
while(stack.size()!=0&& getProperity(str)<=getProperity(stack.peek()) && !stack.peek().equals("(")){
opera.add(stack.pop());
}
stack.push(str);
}
}
//将剩下的字符串放到逆波兰表达式中
while(stack.size()!=0){
opera.add(stack.pop());
}
return opera;
}
public static int compute(int num1,int num2,String topOperator){
double sum =0;
switch(topOperator){
case "+": sum = num1+num2; break;
case "-": sum = num2-num1; break;
case "*": sum = num1*num2;break;
case "/": sum = num2*1.0/num1;break;
}
return (int)sum;
}
//逆波兰运算
//从左向右遍历遇到运算符就弹出两个数字进行计算
public static int compute(List<String> list){
Stack<Integer> stack = new Stack();
int i = 0;//遍历的下标
for(;i<list.size();i++){
if(list.get(i).matches("\\d+")){
stack.push(Integer.parseInt(list.get(i)));
}else{
String str = list.get(i);
int num1 = stack.pop();//栈顶
int num2 = stack.pop();//次顶
int sum = compute(num1,num2,str);
stack.push(sum);
}
}
return stack.peek();
}
public static void main(String[] args) {
String expression = "((12+12)/2-20/2)*8";
List<String> list = toInfixExpressionList(expression);
//逆波兰表达式
List<String> list1 = changePoly(list);
//逆波兰运算
int sum = compute(list1);
System.out.println(sum);
}
}
逆波兰计算器-中缀表达式转后缀表达式
最新推荐文章于 2022-03-15 02:11:29 发布