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

相关推荐
05候补工程师13 小时前
【408考研·OS】核心考点:中断分类、线程模型 (KLT/ULT) 与调度算法方法论总结
经验分享·笔记·考研·算法
多加点辣也没关系14 小时前
数据结构与算法|第十二章:图
数据结构·算法
MClink14 小时前
小米开源大模型 MiMo 登顶全球第一,还白送百万亿 Token?手把手教你薅羊毛
人工智能·python·算法·openai·架构设计
李游Leo14 小时前
TypeScript + React 全栈学习:别只背语法,先把项目链路跑通
学习·react.js·typescript
SH2025091714 小时前
2026适合备考大学生上网课使用的考试季学习辅助工具推荐
学习
阿正的梦工坊14 小时前
认证、授权、JWT、密码哈希:Node.js 鉴权到底在做什么
算法·node.js·哈希算法
sali-tec14 小时前
C# 基于OpenCv的视觉工作流-章67-线线间距
图像处理·人工智能·opencv·算法·计算机视觉
蓝桉~MLGT14 小时前
中级软考(软件工程师)常用错题整理
学习·中级软考
_李小白14 小时前
【android opencv学习笔记】Day 9: 颜色检测算法
android·opencv·学习
TANGLONG22214 小时前
【C++】STL基础必备:深入解析vector容器的实现(含源码)
c语言·开发语言·数据结构·c++·笔记·算法·stl