not fastest but play around with design patterns


  • 0
    L

    public class Solution {
    // state pattern context
    private static interface Context {
    String process(String expression);

    	void addNumerator(int num);
    
    	void addDenominator(int deno);
    
    	void addOperator(int op);
    
    	State getNumeratorState();
    
    	State getDenominatorState();
    }
    
       // state interface
    private static interface State {
    	public State process(char c, Context context);
    
    	public void reset();
    
    	public void end(Context context);
    }
    
    private static class Numerator implements State {
    	private int numerator = 0;
    	private boolean negtive = false;
    
    	public State process(char c, Context context) {
    		if (c == '-') {
    			negtive = true;
    			return this;
    		} else if (c == '/') {
    			context.addNumerator(negtive ? -numerator : numerator);
    			reset();
    			return context.getDenominatorState();
    		} else {
    			numerator = numerator * 10 + c - '0';
    			return this;
    		}
    	}
    
    	public void reset() {
    		numerator = 0;
    		negtive = false;
    	}
    
    	public void end(Context context) {
    		throw new IllegalArgumentException("can not end with numerator");
    	}
    }
    
    private static class Denominator implements State {
    	private int denominator = 0;
    
    	public State process(char c, Context context) {
    		if (c >= '0' && c <= '9') {
    			denominator = denominator * 10 + c - '0';
    			return this;
    		} else {
    			context.addDenominator(denominator);
    			context.addOperator(c);
    			reset();
    			return context.getNumeratorState();
    		}
    	}
    
    	public void reset() {
    		denominator = 0;
    	}
    
    	public void end(Context context) {
    		context.addDenominator(denominator);
    	}
    }
    
    private static class CalContext implements Context {
    	private final State NUMERATOR = new Numerator();
    	private final State DENOMINATOR = new Denominator();
    	private List<Integer> numerators = new ArrayList<>();
    	private List<Integer> denominators = new ArrayList<>();
    	private List<Boolean> operators = new ArrayList<>();
    	private int numerator = 0;
    	private int denominator = 1;
                // "template method"
    	public String process(String expression) {
    		parse(expression);
    		calculate();
    		normalize();
    		return numerator == 0 ? "0/1" : numerator + "/" + denominator;
    	}
    
    	private void parse(String expression) {
    		State s = NUMERATOR;
    		for (char c : expression.toCharArray()) {
    			s = s.process(c, this);
    		}
    		s.end(this);
    	}
    
    	private void calculate() {
    		for (int d : denominators) {
    			denominator *= d;
    		}
    
    		numerator = numerators.get(0) * denominator / denominators.get(0);
    
    		for (int i = 0; i < operators.size(); i++) {
    			numerator += (operators.get(i) ? 1 : -1) * numerators.get(i + 1) * denominator
    					/ denominators.get(i + 1);
    		}
    	}
    
    	private void normalize() {
    		if(numerator == 0) return;
    		int a = denominator;
    		int b = numerator > 0 ? numerator : -numerator;
    		int mod = a % b;
    		while(mod != 0) {
    			a = b;
    			b = mod;
    			mod = a % b;
    		}
    		
    		numerator /= b;
    		denominator /= b;
    	}
    
    	public void addNumerator(int num) {
    		numerators.add(num);
    	}
    
    	public void addDenominator(int deno) {
    		denominators.add(deno);
    	}
    
    	public void addOperator(int op) {
    		if (op == '+')
    			operators.add(true);
    		else
    			operators.add(false);
    	}
    
    	public State getNumeratorState() {
    		return NUMERATOR;
    	}
    
    	public State getDenominatorState() {
    		return DENOMINATOR;
    	}
    }
    
    public String fractionAddition(String expression) {
    	return new CalContext().process(expression);
    }
    

    }


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.