Problem
Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
If the fractional part is repeating, enclose the repeating part in parentheses.
For example,
Given numerator = 1, denominator = 2, return "0.5". Given numerator = 2, denominator = 1, return "2". Given numerator = 2, denominator = 3, return "0.(6)".
Java Solution
See internal comments in the code.
public String fractionToDecimal(int numerator, int denominator) { if (numerator == 0) return "0"; if (denominator == 0) return ""; String result = ""; // is result is negative if ((numerator < 0) ^ (denominator < 0)) { result += "-"; } // convert int to long long num = numerator, den = denominator; num = Math.abs(num); den = Math.abs(den); // quotient long res = num / den; result += String.valueOf(res); // if remainder is 0, return result long remainder = (num % den) * 10; if (remainder == 0) return result; // right-hand side of decimal point HashMap<Long, Integer> map = new HashMap<Long, Integer>(); result += "."; while (remainder != 0) { // if digits repeat if (map.containsKey(remainder)) { int beg = map.get(remainder); String part1 = result.substring(0, beg); String part2 = result.substring(beg, result.length()); result = part1 + "(" + part2 + ")"; return result; } // continue map.put(remainder, result.length()); res = remainder / den; result += String.valueOf(res); remainder = (remainder % den) * 10; } return result; } |
I solve it in another way.
https://github.com/chanshukwong/Recurring-Decimal
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class A_Simple_Fraction {
static class MyReader {
BufferedReader input = null;
StringTokenizer st = null;
public MyReader() {
input = new BufferedReader(new InputStreamReader(System.in));
}
Integer nextInt() {
return Integer.parseInt(next());
}
Long nextLong() {
return Long.parseLong(next());
}
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(input.readLine().trim());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
}
public static void main(String[] args) {
MyReader input = new MyReader();
int testCase = input.nextInt();
while (testCase-- > 0) {
int n = input.nextInt();
int d = input.nextInt();
doSimpleFraction(n, d);
System.out.println();
}
}
private static void doSimpleFraction(int n, int d) {
StringBuilder sb = new StringBuilder("");
StringBuilder afterDecimmal = new StringBuilder("");
HashMap mods = new HashMap();
boolean isInfinite = true;
int beforeDec = n / d;
int reminder = n % d;
int charPos = 0;
sb.append(beforeDec);
if (reminder == 0) {
System.out.print(sb);
return;
}
while (!mods.containsKey(reminder) && reminder != 0) {
mods.put(reminder, charPos++);
int newN = reminder * 10;
if (newN != 0) {
afterDecimmal.append(newN / d);
}
reminder = newN % d;
if (reminder == 0) {
isInfinite = false;
}
}
if (isInfinite) {
int pos = mods.get(reminder);
String s1 = "." + afterDecimmal.substring(0, pos);
String s2 = afterDecimmal.substring(pos);
System.out.print(sb + s1 + "(" + s2 + ")");
} else {
System.out.print(sb + "." + afterDecimmal);
}
}
}
This solution would fail for the fraction 667/10000 because it assumes the first repeating number will continue to repeat.
Time limit is getting exceeded in the above code.
long nume = Math.abs((long)numerator);
long deno = Math.abs((long)denominator);
String sign = (numerator < 0) ^ (denominator < 0) ? "-" : "";
if (deno == 0) {
return "";
} else if (nume == 0) {
return "0";
} else if (nume % deno == 0) {
return sign + nume/deno + "";
}
HashMap map = new HashMap();
StringBuffer rst = new StringBuffer(sign + nume/deno + ".");
long end = nume%deno * 10;//The decimal portion of the value, after decimal point
int i = 0;
while (end != 0){
if (map.containsKey(end)) {
rst.insert(rst.indexOf(".") + map.get(end) + 1, "(");
rst.append(")");
return rst.toString();
}
rst.append(end/deno);
map.put(end, i++);
end = (end % deno) * 10;
}
return rst.toString();
}
}