Fraction to Recurring Decimal|leetcode题解

来源:互联网 发布:知乎 怎么搜文章 编辑:程序博客网 时间:2024/05/23 12:21

这个题目由于有很多的特殊状况,所以错误提交了很多次。

下面是AC代码,耗时4ms

string fractionToDecimal(int numerator, int denominator) {      //首先对0进行判断,以防对最终符号的异或运算结果有干扰           if(0==numerator)return "0";        if(0==denominator)return "";      //使用异或的方式,判断两个数相除的符号,非常好用       bool sign=(numerator<0)^(denominator<0)?true:false;        //防止溢出,使用long long        long long lnumerator=llabs(numerator),ldenominator=llabs(denominator);        long long integer=lnumerator/ldenominator;            stringstream ss;         ss<<integer;        string left=ss.str();        left=(sign?"-":"")+left;        ss.str("");ss.clear();        if(0==lnumerator%ldenominator)return left;         lnumerator%=ldenominator;               map<long long,int>loopPos;            string right="";        bool loop=false;        int index=0;        int nZero=0;        while(lnumerator){            int i=1;            while((long long)lnumerator*pow(10,i)<ldenominator)i++;            long long t=lnumerator*pow(10,i);            if(loopPos.count(t)){                loop=true;                index=loopPos[t];                nZero=i-1;                break;            }            index+=i;            loopPos.insert(pair<long long,int>(t,index));            lnumerator=t%ldenominator;            long long quotient=t/ldenominator;            for(int j=1;j<=i-1;j++)ss<<0;            ss<<quotient;        }           right=loop?ss.str().substr(0,index-1-nZero)+"("+ss.str().substr(index-1-nZero)+")":ss.str();            return left+"."+right;    }

此问题的基本思路,是确定循环小数循环开始和结束的地方,因此要使用散列表记录曾经出现的被除数,如果重复出现,则认为是循环小数。

循环小数结束的地方就是此时商所在的下标的前一位置。

但是循环小数开始的地方,并非是循环小数商首次出现的位置,因为这个商之前可能出现多个前导0,个数用nZero表示。

另外,此题运算过程中,不要使用int,我的编译器由于int和long所占位数相同,因此,为了避免越界,只能使用long long类型。

如果使用int类型,则可能出现INT_MIN的越界,并且此时abs(INT_MIN)依然是INT_MIN,无法在正数域进行计算。

另外,如果不打算在正数域进行计算,则余数的处理非常麻烦,因为在c++中,取余运算得到的余数的符号和被除数符号一致,

并且有可能和其他程序的规则不同,因此需要对被除数的符号进行判断,这样写较为麻烦,建议转到正数域运算。

0 0
原创粉丝点击