Fraction to Recurring Decimal
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)”.
Credits:
Special thanks to @Shangrila for adding this problem and creating all test cases.
10/9/2015 update
So many corner cases we need to take care.
- use long variables for denominator, nominator, remainder and quotient to avoid overflow.
- Convert denominator and nominator to non-negative integer and record the sign symbol in flag.
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
string ans;
string integer;
string fraction;
unordered_map<long, int> map;//remain, index
//index points to the digits that the recurring begins
long above = numerator;
long below = denominator;
long remain = 0;
int flag = 1;
if(above < 0){
above *= -1;
flag *= -1;
}
if(below < 0){
below *= -1;
flag *= -1;
}
integer = to_string(above / below);
remain = above % below;
map[remain] = 0;
int index = 0;
int quotient;
while(remain != 0){
index++;
quotient = (remain * 10) / below;
remain = (remain * 10) % below;
fraction.push_back(quotient + '0');
if(map.find(remain) == map.end()){
//a new remain
map[remain] = index;
}
else{
int start = map[remain];
fraction.insert(fraction.begin() + start, '(');
fraction.push_back(')');
break;
}
}
ans = integer;
if(!fraction.empty()){
ans.push_back('.');
ans.append(fraction);
}
if(flag == -1 && stof(ans) != 0){
ans.insert(ans.begin(),'-');
}
return ans;
}
};
- We must convert int to long to avoid overflow.
- use flag to resolve negative quotient.
//Could the numerator and denominator be negative?
//Could the numerator be 0?
//Could the numerator or denominator excced 2^32
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
string re;
long lnumerator = numerator;
long ldenominator = denominator;
int flag = 1;
//extreme case
if(numerator == 0){
re.push_back('0');
return re;
}
if(lnumerator < 0){
flag *= -1;
lnumerator *= -1;
}
if(ldenominator < 0){
flag*= -1;
ldenominator *= -1;
}
//ordinary case
//is it enough?
string fraction;
unordered_map<long, int> remainders;
long integer = 0;
long mod = 0;
integer = lnumerator / ldenominator;
mod = lnumerator % ldenominator;
re = to_string(integer);
if(flag == -1){
re.insert(0, "-");
}
//just a integer
if(mod == 0) return re;
remainders[mod] = 0;
while(mod != 0){
mod = mod * 10;
int quotient = mod / ldenominator;
mod = mod % ldenominator;
fraction.push_back(quotient + '0'); // BUG HERE: mod means next quotient will repeat rather than the current quotient
if(remainders.find(mod) != remainders.end()){
//mod exists in remainders
string part1 = fraction.substr(0, remainders[mod]);
string part2 = fraction.substr(remainders[mod], -1);
re.push_back('.');
re.append(part1);
re.push_back('(');
re.append(part2);
re.push_back(')');
return re;
}
else{
//mod does not exists in remainders
remainders[mod] = fraction.size();
}
}
//the number is dividable
re.push_back('.');
re.append(fraction);
return re;
}
};
