题目:
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)".
思路:
需要注意一些corner cases(例如分子或分母为零的情况,以及由于除以-1而导致的int类型数字溢出的情况等),具体可以参考下面的代码片段。这里说一下核心思路:1)处理整数部分,很简单,无须赘述;2)如果fraction的结果不是整数,那么给结果字符串添加“.”,并且处理小数部分。在处理小数部分的时候,需要建立一个哈希表,哈希表的key是余数,value是出现此余数时结果字符串的长度。如果余数不为零,则首先在哈希表中查找该余数是否出现过,如果出现过,则说明我们已经遇到了小数中的循环部分,此时在适当位置加上括号,返回结果;否则我们就在哈希表中添加该余数,并且更新余数和结果字符串,进入下一层循环。
代码:
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
string ret;
if(denominator == 0) { // invalid input
return "";
}
if(numerator == 0) { // special case
return "0";
}
long long numers = abs((long long)numerator); // in case of overflow
long long denoms = abs((long long)denominator);
bool negative = (numerator > 0) ^ (denominator > 0);
// integer part
if(negative) {
ret += "-";
}
ret += to_string(numers / denoms);
long remain = numers % denoms;
if(remain == 0) {
return ret;
}
ret += ".";
unordered_map<long, int> hash; // map from remain to index
while(remain != 0) {
if(hash.count(remain) > 0) {
ret.insert(ret.begin() + hash[remain], '(');
ret += ')';
return ret;
}
else {
hash[remain] = ret.size();
remain *= 10;
ret += to_string(remain / denoms);
remain = remain % denoms;
}
}
return ret;
}
};