常见算法<一>

逆波兰表达式(Reverse Polish Notation)

1. 在算法中常说的后缀表达式,简单来说就是将正常的四则运算换一个写法

1+2 = 3  ->   12+ = 3

在习惯了这样的表达方式之后,我们将四则运算快速的转换成以下的表达方式,这里抄袭几个网上的例子:

["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9

["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6

利用栈的方式来处理这样的后缀表达式是非常方便的,他的原理也变得很简单易懂:

  • 从左至右依次读取
  • 遇到符号取出前两位的数字(利用栈的特性,先进先出)
  • 按照符号计算后,将结果再次压入栈内
  举个例子: ["2", "1", "+", "3", "*"]  逐步分解:
  1. 模拟栈:从左至右读取放入栈,数据从栈顶输入即入口,从栈底被推出即出口。依次读入2,1两个数字放入栈
  2. 模拟栈:读取到符号【+】,不放入栈,连续从栈底取数,依次取出2位:2,1进行加法运算。得到的3再次压入栈内。到此为止,栈内只有3这一个数
  3. 模拟栈:继续读取列表,【+】号后面是数字3,放入栈内。目前栈内有两个3
  4. 模拟栈:继续读取列表,符号【*】,不放入栈,连续从栈底取数,依次取出2位:3,3进行乘法运算。得到的9再次压入栈内
  5. 模拟栈:继续读取列表,列表结束无结果,从栈底推出一位:9;此值即为答案

从这个例子来看,利用堆栈的特性能非常简单的用程序来完成这个四则运算。没有括号,不用作特殊判定,非常简便。但是还没有想好,怎么能非常方便的将中缀表达式转换成后缀表达式,或者这个思路本身就是错的?因该被运用在其他场景中。
下面献上计算后缀表达式的代码:其实理解思路后,代码已经不那么重要了(代码也是转自网上的哈)
public class Test {
 
	public static void main(String[] args) throws IOException {
		String[] tokens = new String[] { "2", "1", "+", "3", "*" };
		System.out.println(evalRPN(tokens));
	}
 
	public static int evalRPN(String[] tokens) {
		int returnValue = 0;
		String operators = "+-*/";
 
		Stack<String> stack = new Stack<String>();
 
		for (String t : tokens) {
			if (!operators.contains(t)) {
				stack.push(t);
			} else {
				int a = Integer.valueOf(stack.pop());
				int b = Integer.valueOf(stack.pop());
				switch (t) {
				case "+":
					stack.push(String.valueOf(a + b));
					break;
				case "-":
					stack.push(String.valueOf(b - a));
					break;
				case "*":
					stack.push(String.valueOf(a * b));
					break;
				case "/":
					stack.push(String.valueOf(b / a));
					break;
				}
			}
		}
 
		returnValue = Integer.valueOf(stack.pop());
 
		return returnValue;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值