中缀后缀表达式转换与计算



题目:

问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。


中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。

后缀表达式的计算机求值:
与前缀表达式类似,只是顺序是从左至右:
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。


public class Main {

	/**
	 * 中缀表达式变为后缀表达式:(1+2)*((8-2)/(7-4)) 
	 * 遇到操作数,直接输出,并输出一个空格
	 * 若遇到运算符,则必须与栈顶比较,运算符级别比栈顶级别高则进栈,否则退出栈顶元素并输出
	 * 若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止
	 */
	public static void main(String[] args) {
		System.out.println(compute(new Main().transfer("(1+2)*((8-2)/(7-4))")));
		
	}
	/*
	 * 计算:
	 * 到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,
	 * 用运算符对它们做相应的计算,并将结果入栈;
	 */
	public static int compute(String s) { // 计算后缀表达式的值
		Stack<Integer> stack = new Stack<Integer>();
		char[] array = s.trim().toCharArray();
		for (int i = 0; i < array.length && array[i] != ' '; i++) {
			if (array[i] >= '0' && array[i] <= '9') {
				int n = 0;
				while (array[i] >= '0' && array[i] <= '9') {
					n = n * 10 + Integer.parseInt(array[i] + "");
					i++;
				}
				i--;
			} else {
				if (stack.size() >= 2) {
					int num1 = stack.pop();
					int num2 = stack.pop();
					stack.push(cal(num1, num2, array[i]));
				}
			}
		}
		if (!stack.isEmpty()) {
			return stack.pop();
		}
		return -1;
	}
	public static String transfer(String s) {
		String res = "";
		Stack<Character> stack = new Stack<Character>();
		for (int i = 0; i < s.length(); i++) {
			char a = s.charAt(i);
			if (a != ' ') {
				if (a >= '0' && a <= '9') {
					res += a;
					res += " ";
				}else if (a == ')') {
					while (stack.peek() != '(') {
						res += stack.pop();
						res += " ";
					}
					stack.pop();
				} else {
					if (a != '(') {
						if(!stack.isEmpty() && isType(stack.peek()) >= isType(a)) {
							res += stack.pop();
							stack.push(a);
							break;
						}
					}
					stack.push(a);
				}
			}
		}
		if (!stack.isEmpty()) {
			res += stack.pop();
		}
		return res;
	}
	public static int isType(char c) { // 返回运算符的优先级
		if (c == '+' || c == '-') {
			return 1;
		} else if (c == '*' || c == '/') {
			return 2;
		} else {
			return  0;
		}
	}
	public static int cal (int m, int n, char c) {
		int sum = 0;
		if (c == '+') {
			sum = m + n;
		} else if (c =='-') {
			sum = m - n;
		} else if (c =='*') {
			sum = m * n;
		} else if (c =='/') {
			sum = m / n;
		}
		return sum;
	}
}


原文链接:

http://www.cnblogs.com/16crow/p/6545126.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值