Java算法实现——表达式计算

问题描述:输入一个只包含加减乘除和括号的合法表达式,求表达式的值。其中除表示整数。

输入格式:输入一行,包含一个表达式。

输出格式:输出这个表达式的值。

样例输入:1-2+3*(4-5)

样例输出:-4

数据规模和约定:表达式长度不超过100,表达式运算合法且运算过程都在int内进行。


思路描述:主要用栈实现。创建两个栈:数字栈和符号栈,将字符串的字符一个一个进行判断,如果是数字就进入数字栈,如果是符号就先与符号栈栈顶的符号比较优先级,优先级更大就进展,更小或相等就先把栈内符号出栈进行运算(运算时数字栈出栈两个数),再将当前符号进栈。直到字符串判别完成再进行符号栈的检查看是否为空,不为空就可以一次出栈运算(因为符号栈内的符号已经是按优先级顺序排好了的),最后数字栈中剩一个数字,即表示结果。

本代码参照网站代码撰写:

package kuaishou;

import java.util.Scanner;
import java.util.Stack;

public class Code10 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String str = sc.nextLine();
			solution(str);
		}
		sc.close();
	}

	private static void solution(String str) {
		// TODO Auto-generated method stub
		Stack<Integer> numStack = new Stack<>();
		Stack<Character> signalStack = new Stack<>();
		int index = 0;// 记录已经执行的符号数
		int len = str.length();
		// System.out.println("多项式字符串长度:" + len);
		while (index < len) {
			// System.out.println("第" + index + "步++++++++++");
			char c = str.charAt(index); // 取出这一步的符号
			if (c == '(') {
				// System.out.println(c + "------------进栈");
				signalStack.push(c);// 若是左括号就进栈
			}
			// 否则要先判断优先级
			else if (c == '+' || c == '-' || c == '*' || c == '/') {
				int currOperLevel = getOperlevel(c);// 当前符号的优先级
				while (true) {
					int stackOperLevel = 0;// 栈顶元素的优先级
					if (signalStack.isEmpty() == false) {
						Object obj = signalStack.peek();
						stackOperLevel = getOperlevel((char) obj);
					}
					// 若当前元素优先级大于栈顶元素的优先级则入栈
					if (currOperLevel > stackOperLevel) {
						// System.out.println(c + "------------进栈");
						signalStack.push(c);
						break;// 直到让比自己优先级高的符号都出栈运算了再把自己进栈
					} else {// 不能入栈就进行计算
						try {
							char optemp = '0';
							int num1 = 0;
							int num2 = 0;
							if (signalStack.isEmpty() == false) {
								optemp = (char) signalStack.pop();// 取出优先级大的那个符号
							}
							if (numStack.isEmpty() == false) {
								num1 = (int) numStack.pop();
								num2 = (int) numStack.pop();// 取出数据栈中的两个数
							}
							/*
							 * System.out .println(optemp + " " + num1 + " " +
							 * num2); System.out.println(caculateResult(optemp,
							 * num2, num1) + "---------------进栈");
							 */
							numStack.push(caculateResult(optemp, num2, num1));// 将算出来的结果数据再次进入数据栈
						} catch (Exception e) {
							// TODO: handle exception
							System.out.println("多项式不正确1" + str + " " + c);
							e.printStackTrace();
						}
					}
				}
			} else if (c == ')') {// 右括号就返回栈顶元素,右括号是不进栈的
				while (true) {
					char theop = (char) signalStack.pop();
					if (theop == '(') {
						break;
					} else {
						try {
							int num1 = (int) numStack.pop();
							int num2 = (int) numStack.pop();
							/*
							 * System.out.println(" " + num1 + " " + num2);
							 * System.out .println(caculateResult(theop, num2,
							 * num1) + "------------进栈");
							 */
							numStack.push(caculateResult(theop, num2, num1));// 运算括号内的内容
						} catch (Exception e) {
							// TODO: handle exception
							System.out.println("多项式不正确2" + str);
							e.printStackTrace();
						}
					}
				}
			} else if (c >= '0' && c <= '9') {
				int tempIndex = index + 1;
				while (tempIndex < len) {
					char temp = str.charAt(tempIndex);// 取字符串中处于当前字符的下一位
					if (temp >= '0' && temp <= '9') {
						tempIndex++;// 若为数字则继续向后取
					} else {
						break;// 证明数字去完
					}
				}
				String numstr = str.substring(index, tempIndex);// 截取这个字符串则为两个符号之间的数字
				/*
				 * System.out.println("-------------" + numstr +
				 * "----------------");
				 */
				try {
					int numnum = Integer.parseInt(numstr);// 将数字转换成整型便于运算
					// System.out.println(numnum + "-----------进栈");
					numStack.push(numnum);
					index = tempIndex - 1;
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("多项式不正确3:" + str);
					e.printStackTrace();
				}
			}
			index++;
		}
		// 检查符号栈是否为空
		while (true) {
			Object obj = null;
			if (signalStack.isEmpty() == false) {
				obj = signalStack.pop();
			}
			if (obj == null) {
				break;// 为空证明运算已结束
			} else {// 不为空就出栈运算
				char opterTemp = (char) obj;
				int num1 = (int) numStack.pop();
				int num2 = (int) numStack.pop();
				/*
				 * System.out.println(caculateResult(opterTemp, num2, num1) +
				 * "--------------进栈");
				 */
				numStack.push(caculateResult(opterTemp, num2, num1));
			}
		}
		int result = 0;
		try {
			result = (int) numStack.pop();
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("多项式不正确4" + str);
			e.printStackTrace();
		}
		System.out.println(result);
	}

	/*
	 * 计算加减乘除余
	 */
	private static Integer caculateResult(char optemp, int num1, int num2) {
		// TODO Auto-generated method stub
		switch (optemp) {
		case '+':
			return num1 + num2;
		case '-':
			return num1 - num2;
		case '*':
			return num1 * num2;
		case '/':
			return num1 / num2;
		}
		return 0;
	}

	/*
	 * 返回符号优先级
	 */
	private static int getOperlevel(char c) {
		// TODO Auto-generated method stub
		switch (c) {
		case '(':
			return 0;
		case '+':
		case '-':
			return 1;
		case '*':
		case '/':
			return 2;
		default:
			return 0;
		}
	}

}

猜你喜欢

转载自blog.csdn.net/arpospf/article/details/80274230