java解析字符串表达式--逆波兰表达式的计算

上回合我们讲了如何将中缀表达式转换成逆波兰表达式,这回合我们讲一讲如何计算逆波兰表达式。结合这一回合和上一回合,我们将能够实现这样一个功能:计算一个中缀表达式的结果!话不多说,走起来!

问题来由:

读入一个字符串形式的四则运算表达式,输出对应的计算结果。如读入的是“6 * ( 5 + ( 2 + 3) * 8 + 3)”,那么解析后的输出结果应为288。

思路:

一般的计算过程是这样的,首先计算优先级最高的小括号里面的内容,即“( 5 + ( 2 + 3) * 8 + 3)”,
将“2 + 3”的计算结果并存为A,接着用计算“A*8”,并存为B
计算“5+B+3”,结果存为C
最后计算“6*C”,计算完毕
我们可以将这种操作顺序书写如下:

6 5 2 3 + 8 * + 3 + *

这个记法就是逆波兰(reverse Polish)表达式,其求值过程恰好就是上面所描述的过程。逆波兰表达式又叫做后缀(postfix)表达式。在通常的表达式中,运算符总是置于与之相关的两个运算对象之间,所以,这种表示法也称为中缀表示。波兰逻辑学家 J.Lukasiewicz于1929年提出了另一种表示表达式的方法。按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。

后缀表达式计算:

     image

java代码如下:

package qiuzhitest;

public class CountReversePolishNotation {

	//计算逆波兰表达式,这里只考虑了操作数为个位的,不考虑操作数大于两位及以上的,另外负数和小数均不考虑
	public static int countNotation(String notation){
		//新建一个堆,用来存储非运算符的字符
		SequenceStack<String> stack=new SequenceStack<String>();
		//将字符串转换成字符数组
		char[] arr=notation.toCharArray();
		//循环判断字符数组中的所有字符
		for(int i=0;i<arr.length;i++){
			char c=arr[i];
			//如果字符是0-9的,则压入栈
			if(c>='0'&&c<='9'){
				stack.push(c+"");
			}else{//否则的话弹出两个元素,对当前字符进行判断,做相应的处理,并将处理的结果压入栈中
				int a=Integer.parseInt(stack.pop());
				int b=Integer.parseInt(stack.pop());
				if(c=='+'){
					stack.push((a+b)+"");
				}else if(c=='-'){
					stack.push((a-b)+"");
				}else if(c=='*'){
					stack.push((a*b)+"");
				}else{
					//如果除数为0则抛出异常
					if(b==0){
						throw new RuntimeException("除数为0");
					}
					stack.push((a/b)+"");
				}
				
			}
		}
		//栈中的最后一个元素就是计算后的结果
		int total=Integer.parseInt(stack.pop());
		
		return total;
	}
	public static void main(String[] args){
		System.out.println(countNotation("6523+8*+3+*"));
	}
}

算法分析:

计算一个后缀表达式话费的时间是O(N),该算法的计算非常简单,同时不需要知道任何的计算优先级。

到此,我们已经能够实现将一个中缀表达式转换成后缀表达式(逆波兰表达式),并计算出结果。

https://blog.csdn.net/bruce_6/article/details/39182151参考文章:

猜你喜欢

转载自blog.csdn.net/qq_41300571/article/details/83376961