您的位置:首页 > 其它

[Leetcode] Fraction to Recurring Decimal

2015-08-21 16:41 239 查看
[1] Fraction to Recurring Decimal

这个题目可以在下面几个方面得到训练提示

一、对于数学运算的模拟问题应该随时注意溢出问题,防止溢出的一个手段是把int转化为double

二、打印问题:即使是double最后还是要通过int的形式打印出来,如果是double类型使用String,虽然实质上是一个int但是会带有double的特点,也就是带有小数位,如何去掉这些小数位,使用

DecimalFormat format = new DecimalFormat("#.#");

String res = format.format(double)

上面的函数可以将一个double转化为一个int,同时不带有小数点。

三、对于任何分数表示的小数,都是有理数:有限循环小数或者有限不循环小数。

模拟分数的除法,由于所有的余数都是小于除数的,所以这样的除法运算最多进行除数的大小次,之后会有重复的余数出现,从而出现循环。

四、Corner case

这个问题有许多特殊的情况,可以单独拿出来处理:被除数为0,;被除数大于除数,并且可以整除;结果的符号等等

import java.util.*;
import java.text.*;
/*
这个题目应该是一个非常好的题目,有许多地方可以借鉴,并可以给我们的编程上许多提醒
一、由于可能会有溢出的问题,所以在计算过程当中应该使用double类型,为了保险起见。
二、关于结果的返回,我们只考虑正数,我们直接打印double是不可以的,因为存在小数点,如何实现对double的string打印,可以使用DecimalFormat
utility
三、几个Corner case
被除数为0,可以整除:被除数被除数大,可以提前监测;被除数等于除数,直接返回;被除数小于除数,需要迭代求解过程中监测。
四、循环节的监测使用hashmap,记录的内容是从余数到,该余数所以计算出的商在res中的index,方便最后将循环节整个取出,最后重新组装。
五、由于余数不会大于除数,所以我们有一个计算的上界,这里直接for循环就可以。
*/
public class Solution {
public String fractionToDecimal(int numerator, int denominator) {
if(numerator==0)
return "0";
double numerator1 = (double)numerator;
double denominator1 = (double)denominator;
int flag = numerator1 * denominator1 <0 ? -1:1;
numerator1 = numerator1<0? -numerator1:numerator1;
denominator1 = denominator1<0? -denominator1:denominator1;
//是否能整除
if(numerator1>denominator1){
double tmp = Math.floor(numerator1/denominator1);
if(tmp*denominator1==numerator1){
DecimalFormat format = new DecimalFormat("#.#");
String res = format.format(tmp);
/*
-2147483648, 1
For this condition, the middle result will be 21473648,this can not be convert to integer as overflow
How to print it? As we use the positive one only and add the '-' prefix when needed.
We only lies in the DecimalFormat util.
*/
if(flag==-1)
res = "-"+res;
return res;
}
}else if(numerator1==denominator1){
String res = 1+"";
if(flag==-1)
res = "-"+res;
return res;
}
Map<Double,Integer> remainder2index = new HashMap<Double,Integer>();
int integer = (int)Math.floor(numerator1 / denominator1);
double remainder = numerator1 - denominator1 * integer;
String res = "";
int loopstart = 0;
int index =0;
System.out.println(denominator);
for(int i=0;i<denominator1;i++){
System.out.println("remainder is: "+remainder);
if(remainder==0){//can divide full
if(flag==-1){
return "-"+integer+"."+res;
}
return integer+"."+res;
}
if(remainder2index.containsKey(remainder)){//get the whole loop segment
loopstart = remainder2index.get(remainder).intValue();
break;
}
//not contain
remainder2index.put(remainder, index);
int r = (int)Math.floor(remainder * 10 / denominator1);
System.out.println("r is: "+r);
res = res + r;//append the computation result
remainder = (remainder * 10) - r * denominator1;
index++;
}

String looppart = res.substring(loopstart);
String beforeloop = res.substring(0,loopstart);
String tmpres = integer+"."+beforeloop+"("+looppart+")";
if(flag==-1)
return "-"+tmpres;
else
return tmpres;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: