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

相关推荐
你叶不叶1 天前
sap rap 的技术开发自己的学习路径
学习
厚皮龙1 天前
VAE 与世界模型学习总结
学习
小拉达不是臭老鼠1 天前
Unity05_3D数学
学习·unity·游戏引擎
浅念-1 天前
从LeetCode入门位运算:常见技巧与实战题目全解析
数据结构·数据库·c++·笔记·算法·leetcode·牛客
CoovallyAIHub1 天前
无人机拍叶片→AI找缺陷:CEA-DETR改进RT-DETR做风电叶片表面缺陷检测,mAP50达89.4%
算法·架构·github
CoovallyAIHub1 天前
混合训练反而更差?VLM Agent在训练前协调跨数据集标注,文档布局检测F-score从0.860提升至0.883
算法·架构·github
talen_hx2961 天前
《零基础入门Spark》学习笔记 Day 16
笔记·学习·spark
鸿途优学-UU教育1 天前
教材质量——法考培训的根基与底气
算法
_深海凉_1 天前
LeetCode热题100-最大数(179)
算法·leetcode·职场和发展
咬_咬1 天前
go语言学习(map)
开发语言·学习·golang·map