[LeetCode]58. 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)".

Credits:
Special thanks to @Shangrila for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

 
解法:分数一定可以表示为不循环小数(包括整数)或者无限循环小数。无限不循环小数即是无理数。设置一个哈希表,存储每一次的余数,以及该余数在返回结果result中的下标。每一次得到新的余数,就查询该余数是否已经在哈希表中,是的话说明开始循环了,那么直接在result中该余数对应的位置后面插入‘(’,result末尾加上‘)’,结束运算。如果在哈希表中没找到,则继续正常运算。注意不能根据某一个商的循环来判断循环节是否完成,比如1/17=0.(05882352941176470),8就出现了两次,但是结果却不是0.5(8);Hash表设计为<rem, index>是为了方便找到循环节后左括号的插入。
class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        //防止INT_MIN取绝对值超出范围
        long long num = numerator, den = denominator;
        if (den == 0) return "";
        
        bool isNegative = (num > 0 && den < 0) || (num < 0 && den > 0);
        num = num > 0 ? num : -num;
        den = den > 0 ? den : -den;
        // 整数部分
        string res = "";
        res += (isNegative ? "-" : "") + to_string(num / den);
        long long rem = num % den; //注意极小数除以极大数时余数可能超出int范围
        if (rem == 0) return res;
        else res += ".";
        // 小数部分
        unordered_map<int, int> m;
        while (rem != 0) {
            if (m.find(rem) != m.end()) {
                res.insert(m[rem], 1, '(');
                res += ")";
                break;
            }
            m[rem] = res.size(); // 方便插入左括号
            rem *= 10;
            res += to_string(rem / den);
            rem %= den;
        }
        return res;
    }
};

小数转分数:不循环小数转分数很简单,乘以10的幂将小数部分去掉即可;无限循环小数转分数分两种:一是循环节从小数点后第一位开始的,比如0.333(3/9-->1/3)...、0.7272(72/99-->8/11)...,循环节当做分子,循环节有几位就拿几个9当做分母再约分即可;另一种循环节不从小数点后第一位开始,比如0.437272...,乘以100得到43.7272...,可以理解为43+8/11即481/11,前面乘了100因此再除以100,即是481/1100。

原文地址:https://www.cnblogs.com/aprilcheny/p/4940242.html