【C语言刷LeetCode】166. 分数到小数(M)

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

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

示例 1:

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

输入: numerator = 2, denominator = 1
输出: "2"
示例 3:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fraction-to-recurring-decimal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题隐藏了太多细节,稍不注意就容易出问题。

考虑负数不好处理,所以除数与被除数都转成整数处理。这里用abs会出问题,比如abs(-2147483648),所以用的 0 - 负数 得出正数。

扫描二维码关注公众号,回复: 9247225 查看本文章

0 - 负数在遇到-2147483648时,如果用int类型保存,还是会溢出,所以得用 long long 类型。

然后输出小数,到底多少位呢?如何申请内存?如果算出一个小数位,就动态增加一个内存,太麻烦,其实可以直接malloc一个1024大小的字符串数组,记得初始化就行。

接着就是灵活运用sprintf,比如说要添加负号,要添加括号等等。

然后要记得long long 对应的打印类型是 ‘%lld’,如果用%d就又出错了。

接着就是要计算是循环小数还是非循环小数,两个for循环。找到循环小数的起始循环位后,在对应位置添加括号。

总之此题不简单。

int GetFlagNumber(int *b, long long *res, long long denominatorA, int *i, int *j) {
    long long temp;
    
    for (*i = 0; *i < 1023; (*i)++) {
        temp = res[*i] * 10;
        b[*i] = temp / denominatorA;
        res[*i + 1] = temp % denominatorA;

        if (res[*i + 1] == 0) {
            return 1; // 非循环小数  
        }
        
        for (*j = 0; *j < *i+1; (*j)++) {
            if(res[*i + 1] == res[*j]){
                return 2; // 循环小数
            }
        }
    }
    return 0;
}

long long GetGoodNum(long long num) {
    if (num < 0) {
        return 0 - num;
    } else {
        return num;
    }
}

char * fractionToDecimal(int numerator, int denominator){
    long long a = 0;
    long long res[1024] = {0};
    int b[1024] = {0};
    int i,j,k,m;
    long long temp;
    char *out;
    int flag = 0;
    int offset = 0;
    int flagAdd = 0;
    int aCount = 0;
    long long numeratorA;
    long long denominatorA;
    
    if (denominator == 0) return 0;

    out = (char *)malloc(1024);
    memset(out, 0, 1024);
    
    numeratorA = GetGoodNum(numerator);
    denominatorA = GetGoodNum(denominator);

    if(((numerator < 0) && (denominator > 0)) ||
      ((numerator > 0) && (denominator < 0))) {
        sprintf(out, "%c" ,'-');
        offset++;
    }

    a = numeratorA / denominatorA;
    res[0] = numeratorA % denominatorA;
    
    aCount = sprintf(out+offset, "%lld" ,a);
    offset = offset + aCount;
    
    if (res[0] == 0) { // 整数
        return out;
    }
    
    sprintf(out+offset, "%c", '.');
    offset = offset+1;
    
    flag = GetFlagNumber(b, res, denominatorA, &i, &j);

    if (flag == 1) {
        for ( k = 0; k <= i; k++) {
            sprintf(out+offset, "%d" ,b[k]);
            offset++;
        }
    }

    if (flag == 2) {
        for ( k = 0; k < j; k++) {
            sprintf(out+offset, "%d" ,b[k]);
            offset++;
        }
        sprintf(out+offset, "%c" ,'(');
        offset = offset + 1;
        
        for ( m = j; m < i+1; m++) {
            sprintf(out+offset, "%d" ,b[m]);
            offset++;
        } 
        
        sprintf(out+offset, "%c" ,')');
    }

    return out;
}
发布了124 篇原创文章 · 获赞 17 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/jin615567975/article/details/104369226