leetcode 166分数到小数

 

 

手动排除特殊情况;

对于一般情况,使用位运算和加减法来计算除法,使用sign记录结果符号;(这部分为leetcode 29题的答案)

使用hashmap来记录循环体出现的开始位置(如果有的话),使用flag记录有无循环体出现;

class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        if((numerator==INT_MIN||numerator==INT_MAX)&&(denominator==1||denominator==-1)){
            if(numerator==INT_MIN){
                return denominator==1?"-2147483648":"2147483648";
            }
            if(numerator==INT_MAX){
                return denominator==-1?"-2147483647":"2147483647";
            }
        }
        if(denominator==0) return "";
        string res;
        int sign=numerator^denominator;
        if(numerator==0) sign=1;
        long num=labs(numerator),den=labs(denominator),ans=0,r=0;
        for(int i=31;i>=0;i--){
            if((num>>i)>=den){
                ans+=1<<i;
                num-=den<<i;
            }
        }
        r=num;
        
        if(ans==0) res+="0";
        while(ans!=0){
            res+=ans%10+'0';
            ans=ans/10;
        }
        if(sign<0) res+="-";
        reverse(res.begin(),res.end());
        if(r!=0)
            res+=".";
        int rst=0,flag=0;
        unordered_map<int,int>m;
        string right;
        int i=0;
        //此处分数不会是无线不循环小数,因此只需要判断是否除尽和是否循环两个break条件就可以了;
        while(r!=0){
            r*=10;
            if(m.count(r)) {flag=1;break;}
            m[r]=i;
            if(r>den){
                rst=r/den;
                r=r-rst*den;
                right.push_back('0'+rst);
            }else{
                right+="0";
            }
            i++;
        }
        if(flag==1){
            res=res+right.substr(0,m[r])+"("+right.substr(m[r])+")";
        }else{
            res+=right;
        }
        return res;
    }
};

 

posted @ 2019-05-30 15:09  Joel_Wang  阅读(331)  评论(0编辑  收藏  举报