🌕🌕 166. 分数到小数

吞佛童子2022年10月10日
  • algorithm
  • Number
大约 1 分钟

🌕🌕 166. 分数到小数

难度: 🌕🌕

问题描述

img_11.png


解法

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        // 思路:
        // HashMap 存放已经计算过的分母值,判断是否出现重复元素
        if(numerator == 0) {
            return "0";
        }
        // 为防止超范,转化为 long
        long a = (long) numerator;
        long b = (long) denominator;
        boolean pos = true;
        if((a > 0 && (b < 0)) || (a < 0 && b > 0)) {
            pos = false;
            a = a >= 0 ? a: -a;
            b = b >= 0 ? b: -b;
        }
        StringBuilder sb = new StringBuilder();
        long cur = a % b * 10; // 从小数部分开始记录
        long partInt = a / b; // 计算整数部分
        sb.append(partInt);

        // 能被整除,直接返回
        if(cur == 0) {
            if(!pos) {
                sb.insert(0, '-');
            }
            return sb.toString();
        }

        // 不能被整除,计算小数部分
        sb.append('.'); // 加小数点
        if(!pos) {
            sb.insert(0, '-'); // 加负号
        }

        // System.out.println(partInt + " : " + cur);
        int havIndex = sb.length(); // 当前 sb 已有长度,记录下标从这里开始
        HashMap<Long, Integer> map = new HashMap<>();
        map.put(cur, havIndex); // val - 存放下标
        boolean flag = false; // 判断是否出现循环
        String circle = "";
        int curIndex = havIndex;

        while(cur != 0) {
            long app = cur / b;
            sb.append(app); // 先不管小数点,最后判断,只要有前导0,那么小数点就在第一个 0 后面
            curIndex ++;
            long next = cur % b * 10;
            // System.out.println(sb.toString() + "   " + cur + "   " + next);
            if(map.containsKey(next)) {
                // 出现循环
                int preIndex = map.get(next); // 查看上一次出现该值的下标是多少
                circle = sb.substring(preIndex, curIndex);
                flag = true;
                break;
            } else {
                map.put(next, curIndex);
            }
            cur = next;
        }

        // System.out.println(sb.toString() + "  " + circle);
        // 添加小数部分的循环,由于已经得出循环,所以实际上添加的是两边的括号
        if(flag) {
            sb.insert(sb.length() - circle.length(), '(');
            sb.append(')');
        }
        return sb.toString();
    }
}

输出

img_10.png

上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou