利用栈实现一位数四则运算

2+(3*5)/4+8 这个运算表达式相信大家觉得很简单吧,但通过程序怎么实现一位数四则运算的功能呢?这里,我们需要用到一种经典的数据结构,那就是栈。大家都知道,栈是先进后出(FILO)型的,正是这个特性,才能帮助我们实现四则运算功能。

另外,有一个很重要的概念,那就是后序表达式,说到这里,不知道大家还知道前序表达式,中序表达式吗,举个例子:

3+(5-2)/2这是个中序表达式,这正是我们日常用到的,它的后序表达式是352-2/+,如何由中序表达式得到后序表达式呢?是这样的,遍历表达式的每一个字符,遇到数字则直接打印;遇到运算符或者括号就要判断了,如果是高优先级的运算符,如*,/则直接压入栈中,如果是低优先级,如+,-则要判断此时栈顶元素是否是高优先的运算符了,如果是则弹栈,弹出的运算符直接打印,然后再判断栈顶元素是否是高优先级运算符,直到栈顶不是高优先级运算符,此时就可以将这个低优先级算符压入栈中了;如果是 ( 则压栈,如果是)则要将(与其上的其它运算符弹出,记住,此时按弹出顺序打印,(与)不用打印,记住如果遍历运算串后,栈中还有元素,则需要全部按弹出顺序打印。这样,就完成了转换过程。我们发现后序表达式没有(与),而且没有二异性,前序表达式和它很类似,这里就不做介绍了。

得到后序表达式,那怎么计算出最后结果呢?还是上面的那个例子,后序表达式是352-2/+,这里我们还是要用到栈,要遍历后序表达式,遇到数字就压入栈,遇到运算符就弹出栈顶的两个元素进行运算,将计算结果在压入栈。我们来分析一下,3,5,2依序压入栈,然后是-,此时弹出5,2计算结果是3,将3压入栈,此时栈中元素的3,3现在把后面的2再压栈就是3,3,2了,然后是/弹出3,2计算结果1再压栈,栈中元素现在是3,1最后是+,很简单就得到结果4。

过程就是这样,下面是代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

/**
 * 利用栈实现一位数四则运算
 * 
 * @author Administrator
 * 
 */
public class ArithmeticOperation {

	public static void main(String[] args) {
		StringBuffer buffer = new StringBuffer();
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
		// 创建栈对象
		Stack<Character> s1 = new Stack<>();
		Stack<Integer> s2 = new Stack<>();
		try {
			String line = reader.readLine();
			getBackExpression(buffer, line, s1);

			System.out.println(line = buffer.toString());
			System.out.println(getResult(s2, line));

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static int getResult(Stack<Integer> s, String line) {
		char[] array = line.toCharArray();

		for (int i = 0; i < array.length; i++) {
			char c = array[i];
			if (c >= '0' && c <= '9') {
				// 为数字则压栈
				s.push((int)(c-'0'));
			} else {
				int b = s.pop();
				int a = s.pop();
				switch (c) {
					case '+':
						s.push(a + b);
						break;
					case '-':
						s.push(a - b);
						break;
					case '*':
						s.push(a * b);
						break;
					case '/':
						s.push(a / b);
						break;
					default:
						break;
				}
				
				
			}

		}
		
		return s.pop();
	}

	/**
	 * 中序表达式得到后序表达式
	 * 
	 * @param buffer
	 * @param line
	 * @param s
	 * @throws IOException
	 */
	private static void getBackExpression(StringBuffer buffer, String line,
			Stack<Character> s) throws IOException {

		// 将中缀表达式转换为后缀表达式
		char[] array = line.toCharArray();
		Character temp;
		for (int i = 0; i < array.length; i++) {
			char c = array[i];

			if (c >= '0' && c <= '9') {
				// 是数字则直接打印
				buffer.append(c);
			} else if (c == '*' || c == '/' || c == '(') {
				// 直接压栈
				s.push(c);
			} else if (c == '+' || c == '-') {
				if (s.size() != 0) {
					temp = s.peek();
					for (; temp == '*' || temp == '/';) {
						buffer.append(s.pop());
						if (s.size() != 0) {
							temp = s.peek();
						} else {
							break;
						}
					}
				}
				// 将优先级高的运算符弹栈后再压栈
				s.push(c);
			} else if (c == ')') {

				while ((temp = s.pop()) != '(') {
					buffer.append(temp);
				}
			}
		}
		// 将栈中余下的数弹出
		while (s.size() != 0 && (temp = s.pop()) != null) {
			buffer.append(temp);
		}
	}

}


转载于:https://my.oschina.net/u/2434774/blog/646066

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值