leetcode166. 分数到小数

该博客介绍如何将分数转换为小数,特别是在处理循环小数时,利用哈希表记录余数,当发现余数循环时使用括号标记。讨论了处理0余数和可能的溢出情况。
摘要由CSDN通过智能技术生成
传送门

题目: 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
输入: numerator = 1, denominator = 2 输出: “0.5”
输入: numerator = 2, denominator = 3 输出: “0.(6)”

  1. 需要用一个哈希表记录余数出现在小数部分的位置(实际上就是在ans里插入新计算的 商 的位置),
    当发现余数重复了,就可以将重复出现的小数部分用括号括起来, 返回ans
  2. 再出发过程中余数可能为 0,意味着不会出现循环小数,立刻停止程序。

并且要考虑 INT_MIN / -1 这种溢出的情况, 所以采用long 缓冲各个数值

  	public String fractionToDecimal(int numerator, int denominator) {
        if (numerator == 0) return "0";

        StringBuilder ans = new StringBuilder(); 
        if (numerator < 0 ^ denominator < 0) ans.append('-');// 结果前边加负号

        long a = Math.abs(Long.valueOf(numerator));// 两个结果缓冲成long且取绝对值
        long b = Math.abs(Long.valueOf(denominator));
        ans.append(String.valueOf(a / b));  // 整数部分加入ans
        long  mod = a % b;
        if (mod == 0)  return ans.toString(); // 整除了,直接返回

        ans.append('.'); // 没有整除, 加入小数点
        Map<Long, Integer> modMap = new HashMap<>(); // 商 -> 它添加到ans的位置

        while (mod != 0) {  // 还在循环, 如果没有循环小数, mod一定会变成0
            if (modMap.containsKey(mod)) { // 余数重复出现,循环小数
                ans.insert(modMap.get(mod), "(");// 把上一次插入的商位置前面插入(
                ans.append(')');  // 在ans 尾插入 ), 把上次循环插入的商包起来
                return ans.toString();
            }
            modMap.put(mod, ans.length());// 新的商 插入的位置是ans结尾,形成映射
            mod *= 10;    // 余数*10 继续除以除数b 得到 新的商和  新余数
            ans.append(String.valueOf(mod / b)); // 除之后得到的商 加入ans
            mod = mod % b;  //  产生新余数
        }

        return ans.toString();
    }

注意: 插入ans的是每一次的, 余数只是用来判断是不是循环了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值