【题目指路】每日一题:分数到小数
给定两个整数,分别表示分数的分子 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 - 1denominator != 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();
}
}