中缀表达式转后缀表达式完成逆波兰计算器(Java)

代码思路:

原运算式每个字符通过过空格间隔

构造一个建立运算符优先级大小的函数(priority),通过返回int型建立运算符之间的优先级。

将运算式以空格切割转换为数组并依次添加至一个ArrayList数组(list)

因为栈的特性为先入后出,若作为中缀表达式返回,还需倒序,且方法中只需一个栈储存运算符,所以用ArrayList(endList)储存转换后的结果

建立字符栈 operStack做字符中转用处

遍历list

1.若为数字,直接插入到endList中

2.若为运算符:当operStack为空或遍历字符为( 时直接添入栈中

2.1 若运算符为 )时,循环从字符栈中出栈并且添加到endList中,直到循环字符为"(",停止且丢弃"("

      .2若运算符为 +,—,*,/,拿出栈顶字符,通过priority函数做对比,得出优先级。注:出栈运算符要优先回栈,后添加待入栈运算符.(或写方法拿到顶栈值)

2.2.1当拿出的是( 时,不做比较。

2.2.2当待入栈运算符大于或等于出栈运算符时,先返回出栈运算符后将待入栈运算符添加到字符栈中

2.2.3反之将出栈运算符返回栈中,带入栈运算符添加入endList中

3 遍历结束后,将运算符栈中剩下的元素依次添加至endList中

4 返回endList

5构造函数calculate来计算后缀表达式,建立numStack存放数字

6endList传入calculate函数,遍历endList,

6.1若为数字,直接入栈

6.2若为运算符,出栈两个数,与·运算符计算,将结果再次入栈。注:因为栈先入后出的特性,减法和除法,应当是后出栈数在前,先出栈数在后

6.3遍历结束后。栈中只存在一个数,该数为答案。

eg:还是个大学生,总结自己学习内容所用,大佬们勿喷。

代码如下:

import java.util.ArrayList;
import java.util.Stack;

public class PolandNotationAPP {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		String str="1 + ( ( 2 + 3 ) * 4 ) - 5";
		ArrayList<String> list=parseSuffixExpreesionList(str);
		System.out.printf("后缀表达式为:");
		for(String value:list) {
			System.out.printf(value+" ");
		}
		int result=calculate(list);
		System.out.println("\n最后结果为:"+result);
	}
	
public static ArrayList<String> parseSuffixExpreesionList(String str){//中缀表达式转后缀表达式
	ArrayList<String> endList=new ArrayList<String>();//用list存放结果
	Stack<String> operStack=new Stack<String>();//存放运算符的栈
	String[] temp=str.split(" ");//字符串转换为数组
	ArrayList<String> list=new ArrayList<String>();
	for(int i=0;i<temp.length;i++) {//将字符数组遍历添加到一个list中
		list.add(temp[i]);
	}
	for(String value:list) {
		if(value.matches("\\d+")) {//正则表达式判断是否为数字
			endList.add(value);//如果是数字直接添加到endList中
		}else {//如果是字符
			if(operStack.empty()||value.equals("(")) {//字符栈为空或字符为"("时,直接添加到字符栈中
				operStack.push(value);
			}else if(value.equals(")")) {//字符为")"时,循环从字符栈中出栈并且添加到endList中,直到循环
				while(true) {            //字符为"(",停止且丢弃"("
					String stringTemp=operStack.pop();
					if(stringTemp.equals("(")) {
						break;
					}
					endList.add(stringTemp);
				}
			}else {//当为运算符时,通过自写函数priority,比较优先级,当出栈运算符为:")"时,不做比较,直接添加
				String stringTemp=operStack.pop();//注:出栈运算符要优先回栈,后添加待入栈运算符.(或写方法拿到顶栈值)
				int num1=priority(value);
				int num2=priority(stringTemp);
				if(num2==-1) {//出栈运算符为:")"
					operStack.push(stringTemp);
					operStack.push(value);
					continue;
				}
				if(num1>=num2) {//当待入栈运算符大于或等于出栈运算符时,先返回出栈运算符后将待入栈运算符添加到字符栈中
					operStack.push(stringTemp);
					operStack.push(value);
				}else {//反之将出栈运算符返回栈中,带入栈运算符添加入endList中
					operStack.push(stringTemp);
					endList.add(value);
				}
			}
		}
	}
	while(!operStack.empty()) {//将运算符栈中剩下的元素依次添加至endList中
		endList.add(operStack.pop());
	}
	return endList;
} 

public static int priority(String oper) {//通过返回数字建立优先级
	if(oper.equals("*")||oper.equals("/")) {
		return 1;
	}else if(oper.equals("+")||oper.equals("-")){
		return 0;
	}else if(oper.equals("(")) {
		return -1;
	}else {
		System.out.println(oper);
		throw new RuntimeException("符号有问题");
	}
}

public static int calculate(ArrayList<String> list) {
	Stack<String> numStack=new Stack<String>();
	for(String value:list) {
		if(value.matches("\\d+")) {//正则表达式判断是否为数字
			numStack.push(value);
		}else {//如果是运算符,出栈两个数字,做运算,运算结果添加到数字栈中
			int num2=Integer.parseInt(numStack.pop());//因为栈先入后出的特性,减法和除法,应当是后出栈数在前,先出栈数在后
			int num1=Integer.parseInt(numStack.pop());
			int temp=0;
			if(value.equals("+")) {
				temp=num1+num2;
			}else if(value.equals("-")) {
				temp=num1-num2;
			}else if(value.equals("*")) {
				temp=num1*num2;
			}else if(value.equals("/")) {
				temp=num1/num2;
			}else {
				System.out.println("运算符错误");
			}
			numStack.push(""+temp);
		}
	}
	return Integer.parseInt(numStack.pop());//此时栈中唯一的数字就是运算答案
}
}

运算结果为:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值