public class Fraction {
public boolean symbol;
//numerator/denominator
public int denominator;
public int numerator;
public Fraction(int denominator,int numerator,boolean symbol){
this.denominator = denominator;
this.numerator = numerator;
this.symbol = symbol;
}
@Override
public String toString(){
String sym = symbol? "" : "-";
return sym + numerator + "/" + denominator;
}
}
public Solution{
//region 592. Fraction Addition and Subtraction
public String fractionAddition(String expression) {
Fraction result = new Fraction(1,0,true);
char[] expressionArray = expression.toCharArray();
boolean symbol = true;
int numerator = 0;
int denominator = 1;
boolean isAfterSlash = false;
boolean isFirstNum = true;
for (int i = 0; i < expressionArray.length; i ++){
//if it is '-'
if(expressionArray[i] == '-'){
if(i==0){
symbol = false;
}else {
result = fractionAdd(result,new Fraction(denominator,numerator,symbol));
symbol = false;
numerator = 0;
denominator = 1;
isAfterSlash = false;
isFirstNum = true;
}
}else if (expressionArray[i] == '+'){
result = fractionAdd(result,new Fraction(denominator,numerator,symbol));
symbol = true;
numerator = 0;
denominator = 1;
isAfterSlash = false;
isFirstNum = true;
}else if (expressionArray[i] == '/'){
isAfterSlash = true;
isFirstNum = true;
}else {
if(isAfterSlash){
denominator = isFirstNum? expressionArray[i] - '0' : denominator*10 + expressionArray[i] - '0';
isFirstNum = false;
}else {
numerator = isFirstNum? expressionArray[i] - '0' : numerator*10 + expressionArray[i] - '0';
isFirstNum = false;
}
if(i == expressionArray.length -1){
result = fractionAdd(result,new Fraction(denominator,numerator,symbol));
}
}
}
return result.toString();
}
public Fraction fractionAdd(Fraction frac1, Fraction frac2){
int maxDenominator = getLeastCommonMultiple(new int[]{frac1.denominator,frac2.denominator});
int newNumerator1 = frac1.numerator * (maxDenominator/frac1.denominator);
int newNumerator2 = frac2.numerator * (maxDenominator/frac2.denominator);
int totalNumerator = (frac1.symbol?newNumerator1:-newNumerator1) +
(frac2.symbol?newNumerator2:-newNumerator2);
boolean newSymbol = totalNumerator >= 0;
return fractionReducible(maxDenominator,Math.abs(totalNumerator),newSymbol);
}
public Fraction fractionReducible(int denominator, int numerator, boolean symbol){
int maxDenominator = getGreatCommonDivisor(new int[]{denominator, numerator});
return new Fraction(
denominator/maxDenominator,
numerator/maxDenominator,
symbol);
}
public int getGreatCommonDivisor(int[] numArray){
if(numArray[0]==0 || numArray[1]==0){
return numArray[0] ==0? numArray[1]: numArray[0];
}
int remainder = Integer.MAX_VALUE;
while (remainder != 0){
int temp = numArray[0] % numArray[1];
if(temp != 0){
numArray[0] = numArray[1];
numArray[1] = temp;
}
remainder = temp;
}
return numArray[1];
}
public int getLeastCommonMultiple(int[] numArray){
return numArray[0]*numArray[1]/getGreatCommonDivisor(numArray);
}
//endregion
}