蓝桥杯算法训练-表达式计算

2 篇文章 0 订阅
1 篇文章 0 订阅

蓝桥杯算法训练-表达式计算

问题描述

  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。

输入格式

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

输出格式

  输出这个表达式的值。

样例输入

1-2+3*(4-5)

样例输出

-4

数据规模和约定

  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

解题思路

本题是典型的栈的运用,笔者使用java来实现栈,利用LinkedList来进行实现,没有使用java自带的stack。

解题算法:

1、当输入的数字时,我们输入下一个字符,并且进行char -> int的转换,直到下一个字符不是数字时,我们将结果sum压入存放数据的栈中。

2、当输入的是字符时,如果输入的是“+-*/”中的一个,当符号栈为空或者是当我们的当前运算符char优先级大于运算符号栈顶元素时压入栈,否则我们进行一次计算操作,符号栈栈顶符号出栈,与数字栈的栈顶两个元素进行运算,结果压入数字栈中,然后将运算符压入符号栈中。

3、当输入的字符是'('时,我们直接压入符号栈。

4、当输入的字符是‘)’时,我们进行多次计算,不断的拿出符号栈顶元素,直到符号栈顶元素为'('时停止计算。

5、最后,我们将符号栈中所有的符号拿出进行运算,当符号栈空时,输出数字栈中的栈顶元素即为结果。

 

解题代码:50分

import java.util.LinkedList;
import java.util.Scanner;

public class Main {
	private String excute = new String();
	private Stack<Integer> digtalStack;
	private Stack<Character> operatorStack;
	private int length = 0;
	public Main() {
		digtalStack = new Stack<Integer>();
		operatorStack =  new Stack<Character>();
	}
	public static void main(String[] args) {
		Main main = new Main();
		
		main.get();
	}
	private  void get() {
		init();
		for(int i = 0 ;i<length;i++) {
			Character character = excute.charAt(i);
			if(!isDigtal(character)) {
				//是左括号直接入栈
				if(character=='(') {
					operatorStack.push(character);
					continue;
				}else if(character==')') {
					char c = operatorStack.top();
					while(c!='(') {
						calc();
						c= operatorStack.top();
					}
					operatorStack.pop();
				}else {
					//查找r的优先级
					int r = getRank(character);
					if(operatorStack.isEmpty()||r>getRank(operatorStack.top())){
						operatorStack.push(character);
					}else {
						calc();
						operatorStack.push(character);
					}
				}
			}else {
				int t = character-'0';
				i++;
				while(i<length&&isDigtal(excute.charAt(i))) {
					t= t*10 + excute.charAt(i)-'0';
				}
				i--;
				digtalStack.push(t);
			}
		}
		while(!operatorStack.isEmpty()) {
			calc();
		}
		System.out.println(digtalStack.top());
	}
	/**
	 * 输入
	 */
	private void init() {
		Scanner in = new Scanner(System.in);
		excute = in.nextLine();
		length = excute.length();
		in.close();	
	}
	/**
	 * 判断是否是数字
	 * @param character
	 * @return
	 */
	private boolean isDigtal(Character character) {
		String operator = "+-*/()";
		for(int i = 0 ;i<operator.length();i++) {
			if(operator.charAt(i)==character) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 判断我们的优先级
	 * @param c
	 * @return
	 */
	private int getRank(Character c) {  
			if(c=='*' || c=='/')
				return 2;
			else if(c=='+' || c=='-')
				return 1;
			return 0;
	}
	
	/**
	 * 进行表达式的计算
	 * @param a
	 * @param b
	 * @param character
	 * @return
	 */
	private  int calc() {
		int sum = 0;
		Character character = operatorStack.pop();
		int b = digtalStack.pop();
		int a = digtalStack.pop();
		switch (character) {
		case '+':
			sum = a+b;
			break;
		case '-':
			sum = a-b;
			break;
		case '/':
			sum = a/b;
			break;
		case '*' :
			sum = a*b;
			break;
		default : ;
		}
		digtalStack.push(sum);
		return sum;
	}
}
class Stack<T> extends LinkedList<T>{
	
	// 判断栈是否为空
	public boolean isEmpty() {
		return size()==0;
	}
	
	//入栈
	public void push(T t) {
		addFirst(t);
	}
	public T top() {
		return getFirst();
	}
	//出栈
	public T pop() {
		T t = getFirst();
		removeFirst();
		return t;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值