【LeetCode-数学】分数到小数
题目描述
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
示例:
输入: numerator = 1, denominator = 2
输出: "0.5"
输入: numerator = 2, denominator = 3
输出: "0.(6)"
题目链接: https://leetcode-cn.com/problems/fraction-to-recurring-decimal/
思路
模拟人做除法的情况。假设 c = a / b,r = a % b,如果余数 r 不为 0,则将 r*10 后再次除以 b,如果余数 r*10%b 不为 0,那么将 r*10%b 乘以10接着除以 b,如果某一步的余数为 0,则说明除法结束。如果某一步的余数在之前出现过,则说明商出现了循环
所以,我们使用哈希表记录每一步余数的位置 idx,如果出现了循环,则将左括号(
插入到 idx,右括号)
插入到结果的末尾。
代码如下:
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
if(numerator==0) return "0";
if(denominator==0) return "";
long numer = long(numerator); // 转为 long,否则会溢出
long denom = long(denominator);
string ans = "";
if(numer>0 && denom<0 || numer<0 && denom>0) ans += "-"; //是否同号
numer = abs(numer); // 全转为正数求解
denom = abs(denom);
long a = numer / denom; // a 是当前步的商的整数部分
long r = numer % denom; // r 是当前步的余数
ans += to_string(a);
if(r==0) return ans;
unordered_map<int, int> lookup; // 记录余数是否出现过
ans += ".";
int dotIdx = ans.size()-1; // 小数点出现的位置
while(r && lookup.count(r)==0){
lookup[r] = ++dotIdx;
r*=10;
ans+=to_string(r/denom);
r%=denom;
}
if(lookup.count(r)==1){ // 余数在之前出现过,出现循环
ans.insert(lookup[r], "(");
ans+=")";
}
return ans;
}
};
参考
1、https://leetcode-cn.com/problems/fraction-to-recurring-decimal/solution/cmo-ni-ti-jian-dan-yi-dong-by-xiaoneng/
2、https://leetcode-cn.com/problems/fraction-to-recurring-decimal/solution/fen-shu-dao-xiao-shu-by-leetcode/