【每天学习一点算法 2026/094/14】分数到小数

每天学习一点算法 2026/094/14

题目:分数到小数

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

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

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

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

注意,如果分数可以表示为有限长度的字符串,则 必须 返回它。

作者:LeetCode

链接:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xwm8ne/

来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先我们要将整数部分和小数部分分开来处理

整数部分就是很简单,直接用分子除以分母向下取整即可,如果分子对分母取余为 0 表示没有小数,否则就要加上小数点。

然后就是小数部分,我们就需要一位一位的计算:

  1. 首先我们 n 设为分子对分母取余的结果
  2. 将 n 乘以 10,作为新的被除数
  3. 如果 n * 10 大于等于分母:
    • 用他除以分母向下取整,得到的结果放在这一位上
    • n * 10 对分母取余,结果为 0 表示计算结束,否则就要将 n 设为这次取余的结果继续重复步骤
  4. 如果 n * 10 小于分母
    • 这一位为 0
    • 设 n 为 n * 10 继续重复步骤

如果结果没有循环小数就可以通过上面这种方法递归计算出结果,如果有循环的就会进入死循环,所以我们还需要处理循环小数的情况。

其实很容易就可以想到,当 n 重复的时候就代表计算的小数存在循环,我们可以用一个 set 记录出现的 n, 当 n 重复出现的时候就结束递归。具体实现代码如下:

typescript 复制代码
function fractionToDecimal(numerator: number, denominator: number): string {
  if (numerator === 0) return '0' // 分子为 0 结果为 0
  // 依旧需要处理符号的问题
  let flag = false
  if ((numerator > 0 && denominator > 0) || (numerator < 0 && denominator < 0)) {
    flag = true
  }
  numerator = Math.abs(numerator)
  denominator = Math.abs(denominator)
  
  let integer = '' // 整数部分
  // 计算整数部分
  const a = Math.floor(numerator / denominator)
  integer += a
  
  numerator %= denominator // 取余
  if (numerator !== 0) integer += '.' // 判断结果是否为整数
  
  const other: string[] = [] // 存放小数每一位的计算结果
  const set = new Set() // 存储每次的被除数用于判断小数是否循环
  function helper(n: number, m: number) {
    if (n === 0) return // 设置 n 为 0 计算完毕
    if (set.has(n)) {
      // 设置边界开始循环
      const setArr = Array.from(set)
      const start = setArr.findIndex(item => item == n) // 找到循环开始的下标
      // 添加循环括号
      other.splice(start, 0, '(')
      other.push(')')
      return
    }
    set.add(n) // 添加被除数
    if (n >= m) {
      // 被除数大于等于分母
      const a = Math.floor(n / m)
      other.push(a.toString())
      n %= m
    } else {
      // 被除数小于分母
      other.push('0')
    }
    // 递归传递 n * 10
    return helper(n * 10, m)
  }

  helper(numerator * 10, denominator) // 初始放入分子对分母取余的结果 * 10

  return `${flag ? '' : '-'}${integer}${other.join('')}`
};

题目来源:力扣(LeetCode)

相关推荐
董董灿是个攻城狮4 小时前
Opus 4.7 来了,我并不建议你升级
算法
LN花开富贵4 小时前
【ROS】鱼香ROS2学习笔记二
linux·笔记·python·学习·嵌入式
檬柠wan4 小时前
MySQL-数据库增删改查学习
数据库·学习·mysql
无敌昊哥战神4 小时前
【保姆级题解】力扣17. 电话号码的字母组合 (回溯算法经典入门) | Python/C/C++多语言详解
c语言·c++·python·算法·leetcode
脱氧核糖核酸__4 小时前
LeetCode热题100——238.除了自身以外数组的乘积(题目+题解+答案)
数据结构·c++·算法·leetcode
再卷也是菜4 小时前
算法提高篇(1)线段树(上)
数据结构·算法
py有趣4 小时前
力扣热门100题之单词拆分
算法·leetcode
minglie15 小时前
Zynq 开发中的工程文件管理
学习
j_xxx404_5 小时前
C++算法:哈希表(简介|两数之和|判断是否互为字符重排)
数据结构·c++·算法·leetcode·蓝桥杯·力扣·散列表
Aaron15886 小时前
RFSOC+VU13P+RK3588的核心优势与应用场景分析
嵌入式硬件·算法·matlab·fpga开发·信息与通信·信号处理·基带工程