• Medium | LeetCode 166. 分数到小数 | 数学


    166. 分数到小数

    给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数

    如果小数部分为循环小数,则将循环的部分括在括号内。

    如果存在多个答案,只需返回 任意一个

    对于所有给定的输入,保证 答案字符串的长度小于 104

    示例 1:

    输入:numerator = 1, denominator = 2
    输出:"0.5"
    

    示例 2:

    输入:numerator = 2, denominator = 1
    输出:"2"
    

    示例 3:

    输入:numerator = 2, denominator = 3
    输出:"0.(6)"
    

    示例 4:

    输入:numerator = 4, denominator = 333
    输出:"0.(012)"
    

    示例 5:

    输入:numerator = 1, denominator = 5
    输出:"0.2"
    

    解题思路

    模拟手动除法的运算。

    在小数部分, 同样模拟手动除法的算法, 记录所有余数到HashMap里, 如果发生某个余数已经在HashMap存在了, 就认为是已经出现了无限循环, 需要将这部分用括号圈起来。

    public String fractionToDecimal(int numerator, int denominator) {
        // 0 除以任何数都是 0
        if (numerator == 0) {
            return "0";
        }
        // 转成 long, 绕开整形溢出陷阱
        long dividend = numerator, divisor = denominator;
        boolean negitive = false;
        // 判断符号, 同正同负才是正, 否则是负
        if (numerator >= 0 ^ denominator >= 0) {
            negitive = true;
        }
        // 转为正数运算
        dividend = Math.abs(dividend);
        divisor = Math.abs(divisor);
        StringBuilder ans = new StringBuilder();
        // 负数
        if (negitive) {
            ans.append("-");
        }
        // 计算整数部分
        long quotient = dividend / divisor;
        // 加入整数部分
        ans.append(quotient);
        // 计算当前余数
        dividend = dividend % divisor;
        // 没有余数, 说明可以除尽, 没有小数部分
        if (dividend == 0) {
            return ans.toString();
        }
        int idx = -1, curPos = 0;
        Map<Long, Integer> map = new HashMap<>();
        // 下面是除法的手动模拟计算
        StringBuilder builder = new StringBuilder();
        while (dividend != 0) {
            // 余数 * 10 即为当前被除数
            dividend *= 10;
            // 如果当前被除数之前已经出现过了, 那么代表循环开始
            if (map.containsKey(dividend)) {
                // 获得循环节的位置
                idx = map.get(dividend);
                break;
            }
            // 更新 map
            map.put(dividend, curPos);
            // 记录当前结果
            builder.append(dividend / divisor);
            // 计算当前余数
            dividend %= divisor;
            // 更新小数指针位置
            curPos++;
        }
    
        String decmical = builder.toString();
        // 如果 map 中没有元素, 代表没有小数部分
        if (map.size() != 0) {
            ans.append(".");
        }
        // 存在循环节就加入括号, 否则直接加入小数部分
        if (idx != -1) {
            ans.append(decmical, 0, idx);
            ans.append("(");
            ans.append(decmical.substring(idx));
            ans.append(")");
        } else {
            ans.append(decmical);
        }
        return ans.toString();
    }
    
  • 相关阅读:
    PlayMaker 不支持过渡条件
    Unity Inspector 给组件自动关联引用(二)
    C# 重载和默认参数(那种情况下使用更好)
    Unity 开发游戏编写代码的技巧
    C# Conditional特性避免 预处理命令泛滥使用
    在DirectX12中使用Texture
    再探Lua的require
    如何实现水下效果
    n个骰子的点数
    用DirectX12实现Blinn Phong
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14621838.html
Copyright © 2020-2023  润新知