zoukankan      html  css  js  c++  java
  • Basic Calculator

    问题描述

    Implement a basic calculator to evaluate a simple expression string.

    The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

    You may assume that the given expression is always valid.

    Some examples:

    "1 + 1" = 2
    " 2-1 + 2 " = 3
    "(1+(4+5+2)-3)+(6+8)" = 23
    

    Note: Do not use the eval built-in library function. 

    程序

    第一种是普通的方法:先将表达式转成后缀表达式,然后再计算。(TLE)

    将中缀表达式转为后缀表达式

    中缀表达式转为后缀表达式的要点:

    开始扫描;

    数字时,加入后缀表达式;

    运算符:

    a. 若为 '(',入栈;

    b. 若为 ')',则依次把栈中的的运算符加入后缀表达式中,直到出现'(',从栈中删除'(' ;

    c. 若为 除括号外的其他运算符, 当其优先级高于除'('以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低 的或者遇到了一个左括号为止。·当扫描的中缀表达式结束时,栈中的的所有运算符出栈;  

    public List<String> getPostfixExpressionList(String s) {
    		List<String> list = new ArrayList<String>();
    
    		// preprocess
    		s = s.trim();
    		char[] cc = s.toCharArray();
    		String pro_s = "";
    		Stack<String> st = new Stack<String>();
    
    		for (int i = 0; i < cc.length; i++) {
    			char c = cc[i];
    			if (!Character.isDigit(c)) {
    				pro_s += " " + c + " ";
    			} else {
    				pro_s += c;
    			}
    		}
    
    		// operators priority
    		HashMap<String, Integer> opMap = new HashMap<String, Integer>();
    		opMap.put("+", 0);
    		opMap.put("-", 0);
    		opMap.put("*", 1);
    		opMap.put("/", 1);
    
    		String[] items = pro_s.split(" ");
    		for (int i = 0; i < items.length; i++) {
    			String item = items[i].trim();
    			if (item.length() == 0) {
    				continue;
    			}
    			if (item.equals("(")) {
    				st.push(item);
    			} else if (item.equals(")")) {
    				while (!st.peek().equals("(")) {
    					list.add(st.pop());
    				}
    				st.pop();
    			} else if (opMap.containsKey(item)) {
    				if (st.isEmpty() || st.peek().equals("(")
    						|| opMap.get(st.peek()) < opMap.get(item)) {
    					st.push(item);
    				} else {
    					while (!st.isEmpty() && !st.peek().equals("(")
    							&& opMap.get(st.peek()) >= opMap.get(item)) {
    						list.add(st.pop());
    					}
    					st.push(item);
    				}
    			} else {
    				list.add(item);
    			}
    		}
    		
    		while (!st.isEmpty()) {
    			list.add(st.pop());
    		}
    		
    		return list;
    	}
    

     

    第二种是简化的方法,比较巧妙。

    public class BasicCalculator {
    	public int calculate(String s) {
    		if (s == null || s.length() == 0) {
    			return 0;
    		}
    
    		// transform to postfix expression
    		BasicCalculatorII bs2 = new BasicCalculatorII();
    		List<String> postExpressionList = bs2.getPostfixExpressionList(s);
    
    		// calculate
    		Stack<Integer> calStack = new Stack<Integer>();
    		for (String ex : postExpressionList) {
    			if (ex.equals("+")) {
    				int n1 = calStack.pop();
    				int n2 = calStack.pop();
    				calStack.push(n1 + n2);
    			} else if (ex.equals("-")) {
    				int n1 = calStack.pop();
    				int n2 = calStack.pop();
    				calStack.push(n2 - n1);
    			} else if (ex.equals("*")) {
    				int n1 = calStack.pop();
    				int n2 = calStack.pop();
    				calStack.push(n2 * n1);
    			} else if (ex.equals("/")) {
    				int n1 = calStack.pop();
    				int n2 = calStack.pop();
    				calStack.push(n2 / n1);
    			} else {
    				calStack.push(Integer.valueOf(ex));
    			}
    		}
    
    		return calStack.peek();
    	}
    	
    	// only have +, - operators
    	public int calculate2(String s) {
    		if (s == null || s.length() == 0) {
    			return 0;
    		}
    
    		s = s.trim();
    		int res = 0, sign = 1;
    		Stack<Integer> st = new Stack<Integer>();
    
    		for (int i = 0; i < s.length(); i++) {
    			char c = s.charAt(i);
    			if (Character.isDigit(c)) {
    				int cur = c - '0';
    				while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
    					cur = cur * 10 + (s.charAt(i + 1) - '0');
    					++i;
    				}
    				res += sign * cur;
    			} else if (c == '+') {
    				sign = 1;
    			} else if (c == '-') {
    				sign = -1;
    			} else if (c == '(') {
    				st.push(res);
    				res = 0;
    				st.push(sign);
    				sign = 1;
    			} else if (c == ')') {
    				res = st.pop() * res + st.pop();
    				sign = 1;
    			}
    		}
    
    		return res;
    	}
    }
    
  • 相关阅读:
    linq 读取xml
    c# 定时器 自动执行
    如何在一个人输入框中只输入数字
    如何去掉滚动条,
    如何计算任意值之间的随机数呢
    【P2387】魔法森林(SPFA非正解)
    【Luogu】P3203弹飞绵羊(分块)
    【Luogu】P3396哈希冲突(根号算法)
    【Luogu】P2801教主的魔法(分块)
    【Luogu】P3155叶子的染色(树形DP)
  • 原文地址:https://www.cnblogs.com/harrygogo/p/4647978.html
Copyright © 2011-2022 走看看