166. 分数到小数
题目大意¶
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。
如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 104 。
- 示例 1:
- 输入:numerator = 1, denominator = 2
- 输出:"0.5"
- 示例 2:
- 输入:numerator = 2, denominator = 1
- 输出:"2"
- 示例 3:
- 输入:numerator = 4, denominator = 333
- 输出:"0.(012)"
数据范围:
-231 <= numerator, denominator <= 231 - 1denominator != 0
思路&代码¶
当我们做 两个整数相除(得到小数部分) 时,循环节的本质在于:
- 小数部分的生成过程是不断「余数 × 10 再除以除数」;
- 余数的可能取值有限(最多有
除数 - 1种); - 一旦某个余数重复出现,就说明小数部分开始进入循环。
假设我们要算 a / b,其中 a, b 是整数,且 b > 0。
- 先取整部分: \(\text{intPart}=a/b\) 余数:\(r=a\%b\)
- 进入小数部分循环:
每一步:- 把余数乘 10:
r *= 10 - 当前小数位 =
r / b - 更新余数:
r = r % b
- 把余数乘 10:
- 判断循环节:
用一个map<int, int>记录「余数 → 小数位下标」。- 如果某个余数之前出现过,说明小数开始重复,循环节区间就是
[上一次位置, 当前下标)。 - 如果余数变成 0,说明小数部分终止(有限小数)。
- 如果某个余数之前出现过,说明小数开始重复,循环节区间就是