package com.interview.flag.f; import com.interview.basics.model.collection.hash.HashSet; import java.util.Stack; /** * Created_By: stefanie * Date: 14-12-10 * Time: 上午11:03 */ public class F5_SimplifyExpression { static String ONLYNUMBERS = "[0-9]*"; static HashSet<String> operators = new HashSet<>(); static { operators.add("+"); operators.add("-"); operators.add("*"); operators.add("/"); } //x 1 + 3 * 2 2x 5 + * + -> 7x + 13 public String simplify(String[] expression){ Stack<String> stack = new Stack<>(); for(int i = 0; i < expression.length; i++){ String variable = expression[i]; if(operators.contains(variable)){ String second = stack.pop(); String first = stack.pop(); String result = calculate(first, second, variable); stack.push(result); } else { stack.push(variable); } } return stack.pop(); } public String calculate(String first, String second, String operator){ boolean firstIsNumber = first.matches(ONLYNUMBERS); boolean secondIsNumber = second.matches(ONLYNUMBERS); if(firstIsNumber && secondIsNumber){ return calculateNumber(first, second, operator); } else if(firstIsNumber && !secondIsNumber){ StringBuilder builder = new StringBuilder(); String[] parts = second.split(" "); boolean added = false; for(int i = 0; i < parts.length; i++){ String part = parts[i]; if(operators.contains(part)) builder.append(part + " "); else if(part.matches(ONLYNUMBERS)){ added = true; builder.append(calculateNumber(first, part, operator) + " "); } else if(operator.equals("*") || operator.equals("/")){ int j = part.length() - 1; for(; j > 0; j--){ if(part.substring(0,j).matches(ONLYNUMBERS)){ builder.append(calculateNumber(first, part.substring(0,j), operator) + part.substring(j) + " "); break; } } if(j == 0) { builder.append(calculateNumber("1", second, operator) + part + " "); } } else { builder.append(part + " "); } } if((operator.equals("+") || operator.equals("-")) && added == false){ builder.insert(0, first + " " + operator + " "); } return builder.toString(); } else if(!firstIsNumber && secondIsNumber){ String[] parts = first.split(" "); StringBuilder builder = new StringBuilder(); boolean added = false; for(int i = 0; i < parts.length; i++){ String part = parts[i]; if(operators.contains(part)) builder.append(part + " "); else if(part.matches(ONLYNUMBERS)){ added = true; builder.append(calculateNumber(part, second, operator) + " "); } else if(operator.equals("*") || operator.equals("/")){ int j = part.length() - 1; for(; j > 0; j--){ if(part.substring(0,j).matches(ONLYNUMBERS)){ builder.append(calculateNumber(part.substring(0,j), second, operator) + part.substring(j, part.length()) + " "); break; } } if(j == 0){ builder.append(calculateNumber("1", second, operator) + part + " "); } } else { builder.append(part + " "); } } if((operator.equals("+") || operator.equals("-")) && added == false){ builder.append(operator + " " + second + " "); } return builder.toString(); } else { if(operator.equals("+") || operator.equals("-")){ StringBuilder builder = new StringBuilder(); String[] firstParts = first.split(" "); String[] secondParts = second.split(" "); for(int i = 0; i < firstParts.length; i++){ String firstPart = firstParts[i]; if(operator.contains(firstPart)) { builder.append(firstPart + " "); continue; } for(int j = 0; j < secondParts.length; j++){ String secondPart = secondParts[j]; if(firstPart.matches(ONLYNUMBERS) && secondPart.matches(ONLYNUMBERS)){ builder.append(calculateNumber(firstPart, secondPart, operator)); break; } else if(!firstPart.matches(ONLYNUMBERS) && !secondPart.matches(ONLYNUMBERS)){ int p = firstPart.length() - 1; for(; p > 0 && !firstPart.substring(0,p).matches(ONLYNUMBERS); p--); int q = secondPart.length() - 1; for(; q > 0 && !firstPart.substring(0,q).matches(ONLYNUMBERS); q--); builder.append(calculateNumber(p == 0? "1" : firstPart.substring(0, p), q == 0? "1" : secondPart.substring(0, q), operator) + firstPart.substring(p)); break; } } } return builder.toString(); } } return ""; } public String calculateNumber(String first, String second, String operator){ int num1 = Integer.parseInt(first); int num2 = Integer.parseInt(second); switch (operator){ case "+": return String.valueOf(num1 + num2); case "-": return String.valueOf(num1 - num2); case "*": return String.valueOf(num1 * num2); case "/": return String.valueOf(num1 - num2); default: return ""; } } //( x + 1 )* 3 + 2 *( 2x + 5 ) -> x 1 + 3 * 2 2x 5 + * + public String[] convertRPN(String[] expression){ Stack<String> stack = new Stack<String>(); StringBuilder builder = new StringBuilder(); for(int i = 0; i < expression.length; i++){ String variable = expression[i]; if(variable.equals("(")) { stack.push(variable); } else if(operators.contains(variable)){ while(!stack.isEmpty() && highPriority(variable, stack.peek())){ //calculate the high builder.append(stack.pop() + " "); } stack.push(variable); } else if(variable.equals(")")){ while(!stack.isEmpty() && !stack.peek().equals("(")){ builder.append(stack.pop() + " "); } stack.pop(); } else builder.append(variable + " "); } while(!stack.isEmpty()){ builder.append(stack.pop() + " "); } return builder.toString().split(" "); } public boolean highPriority(String op1, String op2){ if((op1.equals("+") || op1.equals("-")) && (op2.equals("*") || op2.equals("/"))) return true; else return false; } public static void main(String[] args){ F5_SimplifyExpression simplifer = new F5_SimplifyExpression(); String expre = "( x + 1 ) * 3 + 2 * ( 2x + 5 )"; String[] expression = expre.split(" "); String[] RPN = simplifer.convertRPN(expression); //x 1 + 3 * 2 2x 5 + * + for(int i = 0; i < RPN.length; i++){ System.out.print(RPN[i] + " "); } System.out.println(); String result = simplifer.simplify(RPN); System.out.println(result); } }