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)".
Analysis:
This problem needs a little bit of thinking, but it's not difficult to handle. The key idea is not about programming, but the procedure of division.For example, lets do 4/7, a table can be easily computed as follows:
dividend divisor quotient remainder
4 7 0 4
-----------------------------------------------
40 7 5 5
50 7 7 1
10 7 1 3
30 7 4 2
20 7 2 6
60 7 8 4
40 7 5 5
From the table we can see that, the quotient are the result: 0. (571428).
Why the computation stops? Because the remainder occurred in previous steps.
How to get the new dividend? 10 times the remainder in previous round.
I think it is now pretty clear how to do the programming part.
Note that
(1) We need to handle the negative number(s).
(2) The remainders is better to save in a list (array, vector), but not a string.
Python code below is more clear and easy to understand the procedure of this algorithm.
Code(C++):
class Solution {
public:
string num2str(long a){
if (a<0){a = -a;}
ostringstream os;
os << a;
return os.str();
}
string fractionToDecimal(int numerator, int denominator) {
if (numerator == 0 || denominator == 0){
return "0";
}
bool pos=true;
if ((numerator<0 && denominator>0)||(numerator>0 && denominator<0)){
pos = false;
}
long numer = abs(numerator);
long denom = abs(denominator);
int l = -1;
vector<string> res;
int maxlen = 1000;
vector<string> mod;
while (mod.size()<maxlen){
res.push_back(num2str(numer / denom));
long m = numer % denom;
if (m == 0){
break;
}
for (int i=0;i<mod.size();i++){
if (mod[i] == num2str(m)){
l = i;
break;
}
}
if (l == -1){
mod.push_back(num2str(m));
numer = m * 10;
}else{
break;
}
}
string r = "";
if (res.size()==1){
r = res[0];
}else{
r=res[0]+".";
for (int i=1;i<res.size();i++){
if (i == l+1){
r += "(";
}
r += res[i];
}
if (l != -1){
r += ")";
}
}
if (pos) {
return r;
}else{
return "-"+r;
}
}
};
Code(Python):
class Solution:
# @return a string
def fractionToDecimal(self, numerator, denominator):
if numerator * denominator < 0:
pos = False
else:
pos = True
numerator = abs(numerator)
denominator = abs(denominator)
maxlen=1000
mod = []
if numerator == 0 or denominator == 0:
return "0"
res = []
l = -1
while len(mod) < maxlen:
res.append(numerator/denominator)
m = numerator % denominator
if m == 0:
break
if m in mod:
l = mod.index(m)
break
else:
mod.append(m)
numerator = m * 10
if len(res) == 1:
s = str(res[0])
else:
s = str(res[0]) + "."
if l == -1:
s = s + "".join([str(n) for n in res[1::]] )
else:
s = s+ "".join([str(n) for n in res[1:l+1]]) + "(" + "".join([str(n) for n in res[l+1::]]) + ")"
if pos:
return s
else:
return "-"+s
No comments:
Post a Comment