题目:
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)".
解题思路:
首先判断结果的正负号:
如果分子、分母异号,结果就是负的。
否则,结果就是正数或者0。
然后我们就不需要再考虑正负号的问题,把分子和分母都转换成正数来处理(注意:INT_MIN取反后的结果会超出int的范围,为了防止溢出,把它们都转换成long long类型。)。
用分子 除以 分母:
如果恰好能够整除,那么结果将只有整数部分。这个商(必要时加上负号)就是最终结果。
如果不能整除,则商是最终结果的整数部分,小数部分由余数来获得。
(余数 * 10) / 分母,它对应着小数部分的第一位。
- 如果能整除,则计算结束。
- 如果不能整除,就得到新的余数:(余数 * 10) % 分母。然后继续重复上面的步骤。
怎么检测小数的无限循环部分呢?
由于每一位小数都是由一个余数计算得到的,因此我们记录这个对应信息。
这样,当我们发现某个余数已经在之前用到过的时候,说明小数部分产生了循环。而循环的开始位置可以由上面记录的对应信息查到。
代码如下:
class Solution { public: string fractionToDecimal(int numerator, int denominator) { bool sign=true; if((numerator<0)&&(denominator>0)||(numerator>0)&&(denominator<0))//异号结果为负,sign是false;同号或者为0,sign是true { sign=false; //printf("111"); } // 转成long long类型,防止溢出。 long long a=abs((long long)numerator); long long b=abs((long long)denominator); // 如果恰好能整除,直接返回除法结果即可。 long long intpart=a/b;//整数部分 long long decpart=a%b;//余数 string res=""; unordered_map<long long,long long>hash; if(decpart==0) { return (sign==false?"-":"")+to_string(intpart); } // 如果不能整除,利用余数来计算小数部分。 while(decpart!=0) { if(hash.find(decpart)!=hash.end()) { res.insert(hash[decpart],"("); res=res+")"; break; } long long digit=(decpart*10)/b; res+=to_string(digit); hash[decpart]=res.size()-1; decpart=(decpart*10)%b; } //if(sign==false) printf("222"); return (sign==false?"-":"")+to_string(intpart)+"."+res; } };
链接:https://www.jianshu.com/p/f68b0a6db84e