【每天学习一点算法 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)

相关推荐
千寻xun3 小时前
一、理论篇-NVME协议学习笔记
笔记·学习·fpga开发·nvme ssd·nvme协议
researcher-Jiang3 小时前
高性能计算之OpenMP——超算习堂学习1
android·java·学习
CS创新实验室4 小时前
算法、齿轮与硅基大脑:数值计算发展简史
人工智能·算法·数值计算
海石5 小时前
1563分的简单题,可能就简单在能被暴力AC
算法·leetcode
海石6 小时前
1400分的dp汗流浃背之【交替子数组计数】
算法·leetcode
奋发向前wcx6 小时前
P2590 树的统计 题目解析
数据结构·算法·深度优先
imbackneverdie7 小时前
AI4S不止于分子药物:以MedPeer为代表的科研基建打开产业新增量
大数据·人工智能·算法·aigc·科研·学术·ai 4s
额鹅恶饿呃7 小时前
C语言中的数据结构和变量
c语言·数据结构·算法
MartinYeung58 小时前
[论文学习]大语言模型安全综述:攻击、防御、对齐、度量与护栏的深度解析
学习·安全·语言模型
AOwhisky9 小时前
Python 学习笔记(第三期)——流程控制:条件判断与循环结构
运维·笔记·python·学习·云原生·流程控制·循环