LOADING

加载过慢请开启缓存 浏览器默认开启

每日一题:分数到小数

【题目指路】每日一题:分数到小数

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

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

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

对于所有给定的输入,保证 答案字符串的长度小于 $10^{4}$ 。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • -2^31 <= numerator, denominator <= 2^31 - 1
  • denominator != 0

题目的意思就是将分数转换为小数形式,并在小数部分是循环小数时,正确地将循环部分用括号括起来。主要是循环小数的记录,需要插入括号,因此可以使用字典来存储循环开始的索引,另外一个需要注意的就是数据范围比较大,要使用long

实现思路就模拟我们正常使用除法计算就行。除不尽的时候,当余数再次出现在字典里,说明已经开始循环了。因为字典的value存储了索引,所以处理结果的时候就可以在索引处插入括号以符合题目要求。

public class Solution {
    public string FractionToDecimal(int numerator, int denominator) {
        if(numerator == 0) return "0";

        StringBuilder result = new StringBuilder();
        
        // 处理符号
        if ((numerator > 0) ^ (denominator > 0)) result.Append("-");

        // 转换为正数进行计算
        long n = Math.Abs((long)numerator);
        long d = Math.Abs((long)denominator);

        result.Append(n / d);
        long r = n % d;

        if(r == 0) return result.ToString();

        result.Append('.');
        Dictionary<long, int> mp = new Dictionary<long, int>();

        // 处理小数部分
        while (r != 0 && !mp.ContainsKey(r)) {
            mp[r] = result.Length;
            r *= 10;
            result.Append(r / d);
            r %= d;
        }

        if (r != 0) {
            int index = mp[r];
            result.Insert(index, "(");
            result.Append(")");
        }
        return result.ToString();
    }
}