166. 分数到小数 Python

文章目录

  • 一、题目描述
      • 示例 1
      • 示例 2
      • 示例 3
  • 二、代码
  • 三、解题思路


一、题目描述

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

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

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

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

示例 1

输入:numerator = 1, denominator = 2
输出:"0.5"

示例 2

输入:numerator = 2, denominator = 1
输出:"2"

示例 3

输入:numerator = 4, denominator = 333
输出:"0.(012)"

提示:
-2^31 <= numerator, denominator <= 2^31 - 1
denominator != 0

二、代码

代码如下:

from decimal import Decimal, getcontext
class Solution:
    def fractionToDecimal(self, numerator: int, denominator: int) -> str:
        getcontext().prec = 10000
        result = Decimal(numerator) / Decimal(denominator)
        numerator = abs(numerator)
        denominator = abs(denominator)
        if result == int(result):
            print(str(int(result)))
            return str(int(result))
        # 显示长度上限为10000,删除末尾无效的0
        str_result = "{:.10000f}".format(result).rstrip('0')
        print("str_result:", str_result)
        # 判断该分数是否为无限循环小数
        is_recurring_decimal = False
        den = denominator
        # 分母如果只包含25的因数就可以化成有限小数
        while den % 2 == 0:
            den //= 2
        while den % 5 == 0:
            den //= 5
        if den != 1:
            is_recurring_decimal = True
        # 寻找小数中循环的部分 ,找余数是否已经出现,如果已经出现了相同的余数,则表示开始循环了
        if is_recurring_decimal:
            print("无限小数")
            quotient = numerator // denominator
            remainder = numerator % denominator
            decimal_part = ""
            remainders = []
            while remainder != 0 and remainder not in remainders:
                remainders.append(remainder)
                quotient = (remainder * 10) // denominator
                decimal_part += str(quotient)
                remainder = (remainder * 10) % denominator
            if remainder == 0:
                return ""  # 分数是有限小数,没有循环部分
            start_index = remainders.index(remainder)
            recurring_part = decimal_part[start_index:]
            print("循环部分为:", recurring_part)
            str_recurring_part = str(recurring_part)
            print(len(str_recurring_part))
            new_str = ""
            for i in range(len(str_result)):
                if str_result[i:i + len(str_recurring_part)] == str_recurring_part:
                    new_str = new_str + "(" + str_recurring_part + ")"
                    break
                else:
                    new_str = new_str + str(str_result[i])
            print(new_str)
            return new_str
        else:
            print("有限小数")
            print(str_result)
            return str_result


三、解题思路

本题本质上是考验长小数的计算和处理,外加寻找长小数的循环部分。在python中采用Decimal库考验实现高精度的计算,题意中表明:“对于所有给定的输入,保证 答案字符串的长度小于 104 。”,所以可以将显示小数的位数设置为104,这样一来可以更好展示所有位数的小数(当小数位数过长时,默认会返回科学计数法的小数,所以需要设置展示的位数),但是随之而来的问题是,有限小数的末尾会出现很多无效的“0”,此时则可以使用python中的.rstrip('0')方法对字符串格式的小数进行处理,该方法能够删除字符串末尾所有指定的字符。
现在已经能够正常的表示有限小数了,但是我们还需要找出无限小数的循环部分,并用括号括起来进行表示,具体思路如下:
① 判断当前分数是不是无限循环小数,判断条件为:如果分母只包含2和5的因数就是有限小数,反之不是。
② 对于有限小数,用字符串返回所有小数位数的结果即可;对于无限循环小数,采用长除法,每次除法时都记录当前余数并存入余数数组中,如果当前余数已经存在数组中,则表示进入了循环,此时记录下循环部分用于后面表示。
③ 循环遍历字符串格式的小数,找到循环部分位于小数中的部分,用括号+循环部分的形式替换掉所有的循环部分,最后返回结果即可。

你可能感兴趣的:(LeetCode中等难度题集,python,算法,leetcode)