leetcode-166-分数到小数(用余数判断有没有出现小数的循环体)

题目描述:

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

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

示例 1:

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

示例 2:

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

示例 3:

输入: numerator = 2, denominator = 3
输出: "0.(6)"

要完成的函数:

string fractionToDecimal(int numerator, int denominator)

说明:

1、这道题给定两个整数,要求将这两个整数相除的结果存储在string中,最后返回string。

如果是无限循环小数,则要求把循环的部分用括号括起来。

2、两个整数相除,结果只有两种可能,一种是有限循环小数,一种是无限循环小数,不可能出现无限不循环小数。

这道题笔者陷入了几个误区,在这里一一列举一下,可能也会有同学跟笔者犯一样的错误。

①看到2/3=0.6666666……,2/7=0.2857142857142857……,3/7=0.4285714285714286……,就以为所有的循环部分都在小数点后最开始出现。

其实不然,比如1/6=0.166666666666666……,循环部分从第二位开始,我们存储在string中也应该是0.1(6)。

②结合了①的错误,产生了新的想法,判断当前这一位有没有出现过,如果有出现过了,那么之前出现的位置开始,到当前位置的前一位,就是循环体。

如果没有出现过,那么继续记录下去,直到出现了重复的或者直接跑完了所有小数部分(有限循环小数)。

但这样还是错误的,因为其实出现重复的位不代表这个时候就开始循环了,比如1315/10000=0.1315,第二个1出现的时候,仍然不是循环。

如果按照上面所说的方法,这时候出现了重复的位,最终结果是0.(13)。

所以究竟循环体出现的标志是什么?我们研究一下1/6。

最开始补零,变成10/6,写成0.1,这时候余数是4。

余数4再去除以6,变成40/6,写成0.16,这时候余数是4,。

余数4再去除以6……

这个时候我们都知道接下来必定是循环体结构了,因为出现了相同的被除数。

所以我们不能把两个整数变成double类型,直接相除,而是应该不断地整数相除,记录余数,余数再去除以除数。

在这个过程中记录余数,如果出现了重复的余数,那么必定是循环体结构了。

③边界条件,比如-2147483648/-1,-1/-2147483648,7/-12等等。

在下面的代码中再详解。

如下为代码:(附详解)

    string fractionToDecimal(int numerator, int denominator)
    {
        if(numerator==INT_MIN&&denominator==-1)//边界条件,没法直接除,因为除完结果溢出
        return "2147483648";
        if(numerator==-1&&denominator==INT_MIN)//边界条件,都是int类型,没法除
        return "0.0000000004656612873077392578125";
        int shang=numerator/denominator,yushu=numerator%denominator;//记录商和余数
        string res;//最终要返回的string
        if(double(numerator)/double(denominator)<0)//如果两个数一正一负
        {
            if(shang==0)//如果商为0
                res=‘-‘+to_string(abs(shang));//可能有的同学疑惑为什么要这样处理,比如7/-12,除完shang为0,但是我们要的是-0
            else
                res=to_string(shang);//如果不为0,那么直接处理
        }
        else//如果都是正数或者都是负数
            res=to_string(shang);//直接处理
        if(yushu==0)//如果余数为0,那么到此为止,返回res就可以了
            return res;
        res+=‘.‘;//如果还有余数,那么要加个小数点
        unordered_map<int,int>record;//记录出现过的余数和余数除以除数得到的商的位置
        while(yushu!=0)
        {
            yushu=abs(yushu);//余数有可能是负的,全都转为正数
            denominator=abs(denominator);//除数也转为正数
            yushu*=10;//余数乘10,作为新的被除数
            if(record.count(yushu))//如果之前出现过了这个余数,那么可以取出循环体了
            {
                int start=record[yushu],end=res.size()-1;//start和end表示循环体的开端和末尾
                res=res.substr(0,start)+‘(‘+res.substr(start,end-start+1)+‘)‘;//加一下括号
				return res;//直接返回
            }
            record[yushu]=res.size();//如果没出现过,那么记录在record中,value是这个余数除以除数得到的商应该放的位置
            shang=yushu/denominator;//更新商
            yushu=yushu%denominator;//更新余数
            res+=to_string(shang);//加入最新的商
        }
        return res;//如果一直没有出现重复的余数,那么最终跳出循环后直接返回res
    }

上述代码实测0ms,beats 100.00% of cpp submissions。

原文地址:https://www.cnblogs.com/king-3/p/9693937.html

时间: 2024-10-23 08:25:08

leetcode-166-分数到小数(用余数判断有没有出现小数的循环体)的相关文章

python - 判断是否为正小数和正整数

判断输入的金额是否为正整数和正小数 def check_float(string): #支付时,输入的金额可能是小数,也可能是整数 s = str(string) if s.count('.') == 1: # 判断小数点个数 sl = s.split('.') # 按照小数点进行分割 left = sl[0] # 小数点前面的 right = sl[1] # 小数点后面的 if left.startswith('-') and left.count('-') == 1 and right.is

在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数)

//在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数) function formatNum(num, n) {//参数说明:num 要格式化的数字 n 保留小数位 num = String(num.toFixed(n)); var re = /(-?\d+)(\d{3})/; while (re.test(num)) num = num.replace(re, "$1,$2") ret

LeetCode 166. Fraction to Recurring Decimal(模拟)

题目 题意:给出一个分数的分子和分母,给出这个分数的小数形式的字符串模式.循环的部分用( 括上. 题解:模拟除法,判断循环体. class Solution { public: map<int,int> m; string fractionToDecimal(int numerator, int denominator) { long long int numerator_ = numerator; long long int denominator_ = denominator; int s

[leetcode] 166. Fraction to Recurring Decimal 解题报告

题目链接: https://leetcode.com/problems/fraction-to-recurring-decimal/ Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in p

【LeetCode】98. Validate Binary Search Tree -判断是否为二叉排序树

一.描述: 二.思路: 二叉排序树(BST),中序遍历的结果一定是非递减序列(来自百度百科): 本题中对于BST的定义是要么大于,要么小与,即遍历结果只能是递增序列,故可以通过判断中序遍历的结果序列是否是递增序列,来判断是否为合法BST: 另一种方法是使用递归: 三.代码: 1.非递归,通过中序遍历结果判断: /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left;

Java for LeetCode 166 Fraction to Recurring Decimal

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses. For example, Given numerator = 1, denominator = 2, retu

leetcode[166] Fraction to Recurring Decimal

For example, Given numerator = 1, denominator = 2, return "0.5". Given numerator = 2, denominator = 1, return "2". Given numerator = 2, denominator = 3, return "0.(6)". 按照上例子实现结果.主要就是如何处理循环的数字. 我们发现如果循环了,那么余数也是出现了循环,所以从余数入手,一

LeetCode (12) Path Sum (二叉树路径和判断)

题目描述 Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example: Given the below binary tree and sum = 22, return true, as there exist a root-to-lea

JS中,如何判断一个数是不是小数?如果是小数,如何判断它是几位小数??

<script type="text/javascript">     var x = 4.23323;//测试的数字     var y = String(x).indexOf(".") + 1;//获取小数点的位置     var count = String(x).length - y;//获取小数点后的个数     if(y > 0) {         alert("这个数字是小数,有" + count + "