LeetCode 166 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

分析

  1. 首先判断符号,使用Math.signum()。如果是正数,返回1;负数,返回-1;是0,返回0。

    Returns the signum function of the argument; zero if the argument is zero, 1.0f if the argument is greater than zero, -1.0f if the argument is less than zero.

  2. 考虑到溢出,辅助变量定义成long。这是因为如果:

    numerator = Integer.MAX_VALUE;
    denominator = Integer.MAX_VALUE – 1;

    那么在numerator * 10 后,就溢出了。

  3. 要取绝对值,因为 -2 % 3 = -2, -2 % -3 = -2

  4. 分析 57 ,余数分别是 5 1 3 2 6 4 5,到5处就出现了循环。因为余数必然在 [0,7) 范围内,如果不能除尽,必然是无限循环小数。循环的位置,就是某余数第一次出现的位置,至当前该余数出现的位置(该余数是所有余数中,第一个出现2次的)。

          ·         ·
        0.7 1 4 2 8 5
        - - - - - - - 
    7 )5 0
        4 9
        - - - - - - - 
          1 0       
            7       
            - - - - -
            3 0     
            2 8     
            - - - - -
              2 0   
              1 4   
              - - - -
                6 0 
                5 6 
                - - -
                  4 0
                  3 5
                  - -
                    5
    

    如上图所示(希望没画错)。在程序中,就是用Map来表示,key是n/10,也就是整数部分除完后,剩下的余数。余数肯定比被除数小;value是key出现的位置。

    map中key和value出现的顺序:

    key     value
     5        0
     1        1
     3        2
     2        3
     6        4
     4        5
    

    下一个 n/10 是5,map中存在,即可在0处插入 ( ,在最后插入 )

代码

    public static String fractionToDecimal(int numerator, int denominator) {

        String sign = "";

        if (Math.signum(numerator) * Math.signum(denominator) < 0) {
            sign = "-";
        }

        long n = Math.abs(numerator);
        long d = Math.abs(denominator);

        String intPart = Math.abs(n / d) + "";

        // 如果整除,直接返回结果
        if (n % d == 0) {
            return sign + intPart;
        }

        // 计算小数部分
        n %= d;
        n *= 10;

        StringBuilder sb = new StringBuilder();
        Map<Long, Integer> mod = new HashMap<Long, Integer>();

        for (int i = 0; n != 0; i++) {

            long q = n / d;

            Integer start = mod.get(n / 10);

            if (start != null) {
                sb.insert(start, "(");
                sb.append(")");
                break;
            }

            sb.append(Math.abs(q));
            mod.put(n / 10, i);

            n %= d;
            n *= 10;
        }

        String fractionalPart = sb.toString();

        return sign + intPart + "." + fractionalPart;
    }
    原文作者:_我们的存在
    原文地址: https://blog.csdn.net/Yano_nankai/article/details/50175829
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞