用栈完成计算一个表达式

用栈完成计算一个表达式

思路:

  1. 通过一个index值(索引),来遍历我们的表达式
  2. 如果发现是一个数字,直接入栈
  3. 如果发现扫描到是一个符号,分情况讨论:
    3.1 如果发现当前的符号栈为空,直接入栈
    3.2 如果符号栈有操作符,就先进行比较,
    如果当前操作符的优先级小于或者等于栈中的操作符,
    从数栈中pop出两个数,再从符号栈中pop出一个符号,进行计算,然后将当前的操作符入栈,如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。
  4. 当表达式扫描完毕,就顺序从数栈和符号栈中pop出相应的数和符号,并运行。
  5. 最后在数栈只有一个数字,就是表达式的结果。

仅支持整数运算

package com.psyche.calculator;

import java.util.Stack;

public class StackCalculatorDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StackCalculator calc=new StackCalculator();
		String str="1+2*3-6/2";
		System.out.println(calc.calc(str));
	}

}

class StackCalculator{
//	private String expression;  //字符串表达式
//	public StackCalculator(String expression) {
//		this.expression=expression;
//	}
	private Stack<Integer> numStack;
	private Stack<Character> operStack;
	private char[] exp;
	
	//操作符的优先级 (* /) > (+ -) 
	public int calc(String expression) {
		 exp=new char[expression.length()];  //字符数组  存放表达式
		exp=expression.toCharArray();
		 numStack=new Stack<Integer>();        //数字栈
		 operStack= new Stack<Character>();  //操作符栈
		
		//遍历字符数组
		for(int i=0;i<exp.length;i++) {  
			//判断该字符是数字还是操作符
			if(exp[i]>='0'&&exp[i]<='9') {  //数字
				numStack.push(Integer.valueOf(exp[i]-48));
			}else if(exp[i]=='+'||exp[i]=='-'||exp[i]=='*'||exp[i]=='/') {  //运算符
				char val = exp[i];
				switch (val) {
				//符号: +----------------------------------------------------------------------------------------------------------------
				case '+':
				
					//1.判断符号栈是否为空,空直接入符号栈
					if(operStack.isEmpty()) {
						operStack.push(val);
					}else {
						
						pushAndCalc(operStack.pop());
						operStack.push(val);
						
						}
					break;
					
					//符号: -    -----------------------------------------------------------------------------------
				case '-':
					//1.判断符号栈是否为空,空直接入符号栈
					if(operStack.isEmpty()) {
						operStack.push(val);
					}else {
						pushAndCalc(operStack.pop());
						//符号压栈
						operStack.push(val);
					}
					break;
					
					//符号: *    -------------------------------------------------------------------------------------------
				case '*':
					
					//1.判断符号栈是否为空,空直接入符号栈
					if(operStack.isEmpty()) {
						operStack.push(val);
					}else {
						//判断 
						if(operStack.peek()=='+'||operStack.peek()=='-') {
							operStack.push('*');
						}else {
							pushAndCalc(operStack.pop());
						//符号压栈
						operStack.push(val);
						}
						
						
							
						}
						
					
				break;
					
					//符号: /   --------------------------------------------------------------------------------------------------
				case '/':
					

					//1.判断符号栈是否为空,空直接入符号栈
					if(operStack.isEmpty()) {
						operStack.push(val);
					}else {
						//判断 
						if(operStack.peek()=='+'||operStack.peek()=='-') {
							operStack.push('/');
						}else {
							pushAndCalc(operStack.pop());
						//符号压栈
						operStack.push(val);
						}
						
						
							
						}
						
					
					break;
					
			

				default:
					break;
				}
			}else {
				throw new RuntimeException("表达式存在非法字符");  //非法字符
			}
			
		}
		//遍历之后若符号栈不为空,弹出所有符号
		while(!operStack.isEmpty()) {
			pushAndCalc(operStack.pop());
		}
		return numStack.pop();
	}
	
	public void pushAndCalc(char oper) {  //弹出字符进行运算
		int val1=numStack.pop();
		int val2=numStack.pop();
		switch (oper) {
	    case '+':
			numStack.push(val2+val1);
			break;
			
		case '-':
			numStack.push(val2-val1);
			break;
			
		case '*':
			numStack.push(val2*val1);
			break;
			
		case '/':
			numStack.push(val2/val1);
			break;
		}
	}
	
}

运行结果
用栈完成计算一个表达式

上一篇:蓝桥杯Java题目求解-分治法-自然数1到N有多少个数的数位中包含2


下一篇:【更新:EXP公开】CVE-2021-3156:Sudo 堆缓冲区溢出漏洞通告