无限循环小数转分数(纯C)

这是以前帮一个哥们做的考研复试题,还是比较有趣的。

首先输入测试数据组数,然后每一组输入的格式为a.b(c),比如:

10
3.1(3)
0.(3)
1.(25)

输出分数形式:

47/15
1/3
124/99

代码和分析如下:

#include <stdio.h>
#include <string.h>

//按照题目条件,设小数是a.b(c)的,比如3.1(3)但是有可能b是空串,比如0.(10)
//思路,拿3.1(3)举例:x = 3.1(3) ; 10x = 31.(3) ; 100x = 313.(3) ; => 90x = 313.(3) - 31.(3) ,循环节将就这样消去了

void extract(char *str, int *pb, int *pc)
{
    char *p = str;
    *pb = *pc = 0;
    if (*p != '(') //能得到b
    {
        do
        {
            *pb = *pb * 10 + *p++ - '0';
        } while (*p != '(');//直到遇到左括号,说明b读完了
    }
    else //得不到b,只能得到c
    {
        *pb = -1;//用-1表示b读取失败
    }
    p++;//跳过左括号
    do
    {
        *pc = *pc * 10 + *p++ - '0';
    } while (*p != ')');//同理取出c,到右括号为止
}

int gcd(int a, int b)//最大公约数
{
    if (!b)
        return a;
    else return gcd(b, a%b);
}

int pow10(int x)//10的x次方
{
    int result = 1;
    while (x--)
        result *= 10;
    return result;
}

int main(void)
{
    int n;
    int a, b, c;
    int M, N, gcd_m_n; //最后结果表示为N/M,因为要化成最简分数所以用gcd_m_n约分
    char buf[16];
    scanf("%d", &n);
    while (n--)
    {
        scanf("%d.", &a);//一定有a,把a和小数点取出,注意是"%d."不是"%d"
        scanf("%s", buf);//剩下的放入缓冲区
        extract(buf, &b, &c);
        // /*测试输入3.1(4) 3.(4)是否识别*/ printf("%d %d %d", a, b, c);
        if (b == -1)
        {
            int c_mul;
            char c_buf[16];
            sprintf(c_buf, "%d", c);
            c_mul = pow10(strlen(c_buf));
            N = c_mul - 1;
            M = a * c_mul + c - a;
            gcd_m_n = gcd(M, N);
            M /= gcd_m_n;
            N /= gcd_m_n;
            printf("%d/%d
", M, N);
        }
        else
        {
            int b_mul, c_mul;
            char b_buf[16];
            char c_buf[16];
            sprintf(b_buf, "%d", b);
            sprintf(c_buf, "%d", c);
            b_mul = pow10(strlen(b_buf));
            c_mul = pow10(strlen(c_buf));
            N = c_mul * b_mul - b_mul;
            M = a * b_mul * c_mul + b * c_mul + c - a * b_mul - b;
            gcd_m_n = gcd(M, N);
            M /= gcd_m_n;
            N /= gcd_m_n;
            printf("%d/%d
", M, N);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/intervention/p/4030874.html