题目描述:

 
给定两个整数,分别表示分数的分子 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。

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

  1. Java实现 LeetCode 166 分数到小数

    166. 分数到小数 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入 ...

  2. leetcode 166分数到小数

    手动排除特殊情况: 对于一般情况,使用位运算和加减法来计算除法,使用sign记录结果符号:(这部分为leetcode 29题的答案) 使用hashmap来记录循环体出现的开始位置(如果有的话),使用f ...

  3. Leetcode 166.分数到小数

    分数到小数 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入: num ...

  4. 关于JS中判断是数字和小数的正则表达式用法

    关于JS中判断是数字和小数的正则表达式用法 正则表达式 正则表达式是由一个字符序列形成的搜索模式. 当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容. 正则表达式可以是一个简单的字符,或一 ...

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

    判断输入的金额是否为正整数和正小数 def check_float(string): #支付时,输入的金额可能是小数,也可能是整数 s = str(string) if s.count('.') == ...

  6. JS限制input输入的为数字并且有小数的时候最多保留两位小数

    JS限制input用户输入的为数字并且有小数的时候最多保留两位小数,代码如下: html部分: <input type="number" onkeypress="r ...

  7. 在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 ...

  8. 19-6/24作业: 将一个double类型的小数,按照四舍五入保留两位小数

    ☞要求 将一个double类型的小数,按照四舍五入保留两位小数 ☞实现方式 1.获得一个double类型的小数 2.使用BigDecimal包的setScale进行操作 3.输出结果 ☞代码内容 pa ...

  9. ✡ leetcode 166. Fraction to Recurring Decimal 分数转换 --------- java

    Given two integers representing the numerator and denominator of a fraction, return the fraction in ...

随机推荐

  1. 2018.08.10 atcoder Median Sum(01背包)

    传送门 题意简述:输入一个数组an" role="presentation" style="position: relative;">anan. ...

  2. Linux服务器部署系列之七—OpenLDAP篇

    LDAP(轻量级目录访问服务),通过配置这个服务,我们也可以在linux下面使用目录的形式管理用户,就像windows下面的AD一样,方便我们管理.下面我们就一起来配置openldap服务.本文运行环 ...

  3. HDU 3897 Base Station (网络流,最大闭合子图)

    题意:给定n个带权点m条无向带权边,选一个子图,则这个子图的权值为 边权和-点权和,求一个最大的权值. 析:把每条边都看成是一个新点,然后建图,就是一个裸的最大闭合子图. 代码如下: #pragma ...

  4. 分享一个以前写的基于C#语言操作数据库的小框架

    一:前言 这个是以前写的操作MySQL数据库的小型框架,如果是中小型项目用起来也是很不错的,里面提供Filter.ModelPart.Relationship等机制实现操作数据库时的SQL语句的拼接和 ...

  5. 如何开发一个产品级的Node.js 应用

    介绍 Node.js是一个开源的javascript运行时环境.非常简单可以快速开发一个网络应用.这个平台运行在Linux.OSX和Windows,而且运行在这个平台上的应用都是用javascript ...

  6. 转:解决windows下eclipse中android项目关联android library project失败问题

    近日,在做一个人人的第三方小项目.打算直接使用renren 的sdk 进行开发.因为renren的sdk是以android library project 形式发布的(关于这种project的内容可以 ...

  7. 集合(四)HashMap

    之前的List,讲了ArrayList.LinkedList,最后讲到了CopyOnWriteArrayList,就前两者而言,反映的是两种思想: (1)ArrayList以数组形式实现,顺序插入.查 ...

  8. Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件

    Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件 在FireMonkey iOS应用程序中使用WebBrowser 在iOS平台上,FireMonkey使用T ...

  9. Android-Java-了解编译

    在多年以前,计算机早期的运行方式是 01010100 ....., 这种方式的时候,开发人员编写代码是把01010101/01100101/01010111 ..... /来汇编写代码,这种方式特别痛 ...

  10. string 和String的区别

    string 是 System.String 的别名,习惯上,我们把字符串当作对象时(有值的对象实体),我们用string.而我们把它当类时(需要字符串类中定义的方法),我们用String,比如: s ...