package com.interview.algorithms.general; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Verify whether an arithmatic expression is valid, suppose the expression only contains "+", "-", "*", "/", "(", ")" * and numbers are positive integers. * Created with IntelliJ IDEA. * User: zouzhile * Date: 7/14/13 * Time: 4:27 PM * To change this template use File | Settings | File Templates. */ public class C1_24_ExpressionValidation { static class Stack { List<Character> data = new ArrayList<Character>(); public void push(char ch) { data.add(ch); } public char pop() { if(data.isEmpty()) return Character.CONTROL; else return data.remove(data.size() - 1); } public boolean isEmpty() { return data.isEmpty(); } public String toString(){ String result = ""; Iterator<Character> itr = this.data.iterator(); while(itr.hasNext()) result = itr.next() + result; return result; } } /** * The idea: Push the content of the expression to a stack. When see a ')', pop out stack chars until see a '(', * this will derives a basic expression inside a pair of parentheses. If all basic expressions are valid, then the * entire expression is valid. * @param expression * @return */ public boolean validate(String expression) { expression = expression.trim().replace("\\s+", ""); if("".equals(expression.trim())) // empty string are valid expressions return true; Stack stack = new Stack(); for(int i = 0; i < expression.length(); i ++) { char current = expression.charAt(i); if(current == ')') { String subExpr = ""; char poppedChar = stack.pop(); while(poppedChar != Character.CONTROL && poppedChar != '(') { subExpr += poppedChar; poppedChar = stack.pop(); } if(! this.validateBasicExpression(subExpr)) return false; else stack.push('9'); // replace the original expression with a number } else stack.push(current); } return this.validateBasicExpression(stack.toString()); } /* Basic expressions are those don't contain parentheses. There are two invalid cases: 1) start or end with an operator 2) continuous operator chars within the expression. 3) unmatched '(' or ')' in the expression */ private boolean validateBasicExpression(String basicExpression){ if("".equals(basicExpression.trim())) return true; char begin = basicExpression.charAt(0); char end = basicExpression.charAt(basicExpression.length() - 1); if (this.isOperator(begin) || this.isOperator(end)) return false; // check on continuous operator chars char previous = Character.CONTROL; for(int i = 0; i < basicExpression.length(); i ++) { char current = basicExpression.charAt(i); if(this.isOperator(previous) && this.isOperator(current) || this.isParentheses(current)) return false; previous = current; } return true; } private boolean isOperator(char ch) { return ch == '+' || ch == '-' || ch == '*' || ch == '/'; } private boolean isParentheses(char ch) { return ch == '(' || ch == ')'; } public static void main(String[] args) { C1_24_ExpressionValidation validator = new C1_24_ExpressionValidation(); String expression = "2+5*(2+4)"; System.out.println(expression + ": " + validator.validate(expression)); expression = "2+)5*(2+4)"; System.out.println(expression + ": " + validator.validate(expression)); expression = "2+(5*(2+4)"; System.out.println(expression + ": " + validator.validate(expression)); expression = "2(5*2)"; System.out.println(expression + ": " + validator.validate(expression)); } }