分数到小数

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

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

示例 1:

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

示例 2:

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

示例 3:

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

这条题目说简单简单。。但是自己实现起来就各种问题。。。

一开始的思路是碰到重复的余数就说明进入了循环,但调试的时候发现不行,比如说1/6,前两次余数都是4。。。后来我改进成被除数。。但是由于我一开始用的是一个长度根据被除数确定的hash表,所以碰到INT_MIN的时候,内存不够了。。。再改。。。然后就是把小数部分和整数部分结合的时候。。。如果是循环小鼠的话,需要在循环部分加 ( ) 。这一段代码弄了很久。。。主要是之前写的贼几把乱。。脑子也贼几把乱。。。最后就是溢出的问题。。。真特么蛋疼。。。总之下面是我的代码,还是很乱。。但至少跑出来了,用时4ms。。。最下面是大佬的代码。。

char* i2a(int num)
{
    char *s=(char *)malloc(sizeof(char)*12);
    int i=0,j=0;
    unsigned n;
    if(num<0)
    {
        n=(unsigned)-num;
        s[i++]='-';
        j++;
    }
    else
        n=(unsigned)num;
    do
    {
        s[i++]=n%10+'0';
        n/=10;
    }
    while(n);
    s[i--]=0;
    char tmp;
    while(j<i)
    {
        tmp=s[j];
        s[j++]=s[i];
        s[i--]=tmp;
    }
    return s;
}
int contain(int *visited,int x,int size)
{
    int i;
    for(i=0;i<size;i++)
        if(visited[i]==x)
            return i+1;
    return 0;
}
char* fractionToDecimal(int numerator, int denominator) {
    long long x,y;
    int i,j,pos,size=0,flag;
    x=numerator<0?(unsigned)-numerator:numerator;
    y=denominator<0?(unsigned)-denominator:denominator;
    flag=(numerator<0)^(denominator<0);
    char *integer;
    if(numerator==INT_MIN&&denominator==-1)
    {
        integer=i2a(INT_MAX);
        integer[9]='8';
    }
    else
        integer=i2a(numerator/denominator);
    int *visited=(int *)malloc(sizeof(int)*10000);
    char *decimal=(char *)malloc(sizeof(char)*10000);
    memset(visited,0,sizeof(int)*10000);
    memset(decimal,0,sizeof(char)*10000);
    x=x%y;
    while(x)
    {
        if((pos=contain(visited,x,size)))
            break;
        visited[size]=x;
        x*=10;
        decimal[size++]=x/y+'0';
        x%=y;
    }
    if(!size)
        return integer;
    decimal[size]='\0';
    int inlen=strlen(integer);
    if(integer[0]=='0'&&flag)
    {
        integer[0]='-';
        integer[1]='0';
        integer[2]='\0';
        inlen++;
    }
    int delen=strlen(decimal);
    char *rs=(char *)malloc(sizeof(char)*(inlen+delen+4));
    for(i=0;i<inlen;i++)
        rs[i]=integer[i];
    rs[inlen]='.';
    if(x)
    {
        for(i=1;i<pos;i++)
            rs[inlen+i]=decimal[i-1];
        rs[inlen+pos]='(';
        for(i-=1,j=0;i<delen;j++)
            rs[inlen+pos+1+j]=decimal[i++];
        rs[inlen+delen+2]=')';
        rs[inlen+delen+3]='\0';
    }
    else
    {
        for(i=0;i<delen;i++)
            rs[inlen+1+i]=decimal[i];
        rs[inlen+delen+1]='\0';
    }
    return rs;
}

这是用时最短的大佬的代码。

char* fractionToDecimal(int numerator, int denominator) {
    int base[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
    int map[1096] = {0};
    char tmp[1096];
    int p = 0;
    int sign = (numerator < 0) ^ (denominator < 0);
    long n1 = numerator < 0 ? -((long)numerator) : (long)numerator;
    long n2 = denominator < 0 ? -((long)denominator) : (long)denominator;
    
    if (sign && numerator) {
        tmp[p++] = '-';
    }

    long integer = n1 / n2;
    if (integer) {
        int i = 9;
        while (integer / base[i] == 0) {
            i--;
        }
        while (i >= 0) {
            tmp[p++] = integer / base[i] + '0';
            integer %= base[i];
            i--;
        }
    } else {
        tmp[p++] = '0';
    }
 
    long frac = n1 % n2;
    int repeat = 0;
    if (frac) {
        tmp[p++] = '.';
    }

    while (frac) {  
        int find = 0;
        for (int i = 0; i < p; i++) {
            if (map[i] == frac) {
                find = i;
                break;
            }
        }
        if (find) {
            repeat = find;
            break;
        } else {
            map[p] = frac;  
        }
        tmp[p++] = frac * 10 / n2 + '0';
        frac = (frac * 10) % n2;
    }
    tmp[p] = '\0';

    int returnsize = p;
    if (repeat) {
        returnsize += 2;    
    }
    char *ret = (char *)malloc(sizeof(char) * returnsize);
    
    if (repeat) {
        strncpy(ret, tmp, repeat);
        ret[repeat] = '(';
        strcpy(ret + repeat + 1, tmp + repeat);
        ret[p + 1] = ')';
        ret[p + 2] = '\0';
    } else {
        strcpy(ret, tmp);
    }
    return ret;
}

猜你喜欢

转载自www.cnblogs.com/onlyandonly/p/9386420.html