【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/

posted @ 2020-07-14 16:23  Flix  阅读(262)  评论(0编辑  收藏  举报