package com.interview.leetcode.math; import java.util.*; /** * Created_By: stefanie * Date: 14-11-20 * Time: 上午10:02 */ public class Expressions { static Set<String> operators = new HashSet<String>(); static { operators.add("*"); operators.add("-"); operators.add("+"); operators.add("/"); } public static int calculate(int num1, int num2, String operator){ switch(operator){ case "+": return num1 + num2; case "*": return num1 * num2; case "-": return num1 - num2; case "/": return num1 / num2; default : return 0; } } public static boolean validInteger(String s){ try{ Integer.parseInt(s); return true; } catch(NumberFormatException e){ return false; } } /** * Verify whether an arithmatic expression is valid, suppose the expression only contains "+", "-", "*", "/", "(", ")" and numbers are integers. * Invalid Case: * 0. ) without (, or ( without ), example: 2+)5*(2+4) or 2+(5*(2+4) * 1. 2 operators together: 5**2 * 2. () and number together: (5*2)2 or 2(5*2) */ public static boolean valid(String str){ boolean prevNumber = false; boolean needOperator = false; for(int i = 0; i < str.length(); i++){ char ch = str.charAt(i); if(ch == ' ') continue; else if(Character.isDigit(ch)) { if (needOperator) return false; // invalid case: (5*2)2 prevNumber = true; } else if(ch == ')') return false; //invalid case: 2+)5*(2+4) else if(ch == '(') { if(prevNumber) return false; //2(2+2) int close = str.lastIndexOf(')'); if(close == -1) return false; //invalid case: 2+(5*(2+4) if(!valid(str.substring(i + 1, close))) return false; //valid substring prevNumber = true; needOperator = true; i = close; } else { //check preNumber if(prevNumber == false) return false; //invalid case: 5**2 prevNumber = false; needOperator = false; } } return true; } static class ReversePolishNotation{ public boolean verify(String[] tokens){ if(tokens.length == 0) return false; Stack<Integer> stack = new Stack<Integer>(); for(String token: tokens){ if(!operators.contains(token)){ if(!validInteger(token)) return false; stack.push(0); } else { if(stack.size() < 2) return false; stack.pop(); } } return (stack.size() == 1)? true : false; } public int eval(String[] tokens) { if(tokens.length == 0) return 0; Stack<Integer> stack = new Stack<Integer>(); for(String token : tokens){ if(!operators.contains(token)) stack.push(Integer.parseInt(token)); else { int num2 = stack.pop(); int num1 = stack.pop(); stack.push(Expressions.calculate(num1, num2, token)); } } return stack.pop(); } public String tranformRPN(String[] tokens){ StringBuilder builder = new StringBuilder(); Stack<String> operatorsStack = new Stack<String>(); for(String token : tokens){ if(token.equals("(") || operators.contains(token)) operatorsStack.push(token); else if(token.equals(")")) popOperators(operatorsStack, builder); else { if(builder.length() > 0) builder.append(" "); builder.append(token); } } popOperators(operatorsStack, builder); return builder.toString(); } public String tranformFromRPN(String[] tokens){ StringBuilder builder = new StringBuilder(); Stack<String> numbers = new Stack<>(); for(String token : tokens){ if(!operators.contains(token)) numbers.push(token); else { String number = numbers.pop(); if(builder.length() == 0) { String number2 = numbers.pop(); builder.append("( " + number2 + " " + token + " " + number + " )"); } else { builder.append(" )"); builder.insert(0, "( " + number + " " + token + " "); } } } return builder.toString(); } public void popOperators(Stack<String> operators, StringBuilder builder){ while(!operators.isEmpty()) { String operator = operators.pop(); if(operator.equals("(")) break; if(builder.length() > 0) builder.append(" "); builder.append(operator); } } } /** * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. */ static class ValidParentheses{ private static final Map<Character, Character> map = new HashMap<Character, Character>() {{ put('(', ')'); put('{', '}'); put('[', ']'); }}; public boolean isValid(String s) { Stack<Character> stack = new Stack<>(); for (char c : s.toCharArray()) { if (map.containsKey(c)) { stack.push(c); } else if (stack.isEmpty() || map.get(stack.pop()) != c) return false; } return stack.isEmpty(); } } }