鱼C论坛

 找回密码
 立即注册
查看: 1798|回复: 1

[已解决]Decimal or Fractional

[复制链接]
发表于 2021-5-1 19:45:43 From FishC Mobile | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
小D在学习C语言的时候遇到了许多奇妙的题目,其中有一题是这样子的:
写一个程序,输入一个形如N/D
N/D
的分数(N
N
是分子,D
D
是分母),输出它的小数形式。 如果小数有循环节的话,把循环节放在一对圆括号中。
小D没过多久就将这题给过掉了。但是小D是一个爱思考的好孩子,他思考如果将有理数化成最简分数形式又该如何做到。
输入样例
1.0
输出样例
1/1
输入数据
输入为1行字符串,保证字符串长度不超过10,为有理数的小数形式。如果小数有循环节的话,把循环节放在一对圆括号中。
输出数据
输出1行,为一个形如N/D
N/D
的最简分数。
样例输入
1.(12)\n
样例输出
37/33 \n
求大佬看看孩子吧,是真的没思路
最佳答案
2021-5-7 17:47:52
工具人来了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_SIZE            1024
#define BOOL                int
#define TRUE                1
#define FALSE               0

//分数结构体
typedef struct _Fraction
{
    //分子
    int numerator;
    //分母
    int denominator;
} Fraction;

//创建分数对象
Fraction CreateFraction(int n, int d)
{
    Fraction result = { n, d };
    return result;
}

//最大公约数
int GreatestCommonDivisor(int a, int b)
{
    if (a == 1 || b == 1) return 1;
    else if (a == b) return a;

    int big     = a > b ? a : b;
    int small   = (a + b) - big;
    int t       = 0;

    while (small > 0)
    {
        t       = small;
        small   = big % small;
        big     = t;
    }

    return big;
}

//最小公倍数
int LeastCommonMultiple(int a, int b)
{
    int gcd = GreatestCommonDivisor(a, b);
    return a * b / gcd;
}

//简化分数
void SimplifyFraction(Fraction* dec)
{
    int g                = GreatestCommonDivisor(dec->numerator, dec->denominator);
    dec->numerator      /= g;
    dec->denominator    /= g;
}

//分数相加
Fraction FractionAdd(Fraction a, Fraction b)
{
    int lcm = LeastCommonMultiple(a.denominator, b.denominator);
    Fraction result = CreateFraction(a.numerator * (lcm / a.denominator) + b.numerator * (lcm / b.denominator), lcm);
    SimplifyFraction(&result);
    return result;
}

//打印分数到屏幕
void PrintFraction(Fraction a) { printf_s("当前分数为: %d/%d \n", a.numerator, a.denominator); }

//有限不循环小数转分数
Fraction FiniteDecimalToFraction(char* numStr)
{
    int n           = 0;        //分子
    int d           = 1;        //分母
    BOOL isPoint    = FALSE;    //是否遇到小数点

    for (int i = 0; i < strlen(numStr); i++)
    {
        if (numStr[i] == '.')
        {
            isPoint = TRUE;
            continue;
        }

        n = n * 10 + (numStr[i] - 0x30);

        if (isPoint)
            d = d * 10;
    }

    Fraction result = CreateFraction(n, d);
    SimplifyFraction(&result);

    return result;
}

//无限循环小数转分数
Fraction InfiniteDecimalToFraction(char* loopStr)
{
    int  ZeroAfterPoint     = 1;        //小数点后,循环节开始前0的个数
    BOOL isPoint            = FALSE;    //是否遇到小数点
    BOOL isStartLoop        = FALSE;    //循环节是否开始
    int  n                  = 0;        //分子
    int  d                  = 0;        //分母

    for (int i = 0; i < strlen(loopStr); i++)
    {
        if (loopStr[i] == '.')
        {
            isPoint = TRUE;
            continue;
        }

        if (isPoint && loopStr[i] != '0')
            isStartLoop = TRUE;

        if (isPoint && !isStartLoop)
            ZeroAfterPoint *= 10;
        else if (isPoint && isStartLoop)
        {
            n = n * 10 + (loopStr[i] - 0x30);
            d = d * 10 + 9;
        }
    }

    Fraction result = CreateFraction(n, d * ZeroAfterPoint);
    return result;
}

//输入
void GetInput()
{
    char finite[MAX_SIZE]   = { 0 };        //有限部分
    char loop[MAX_SIZE]     = { 0 };        //循环部分
    char str[MAX_SIZE]      = { 0 };        //整体
    BOOL isLeftBracket      = FALSE;        //是否遇到左括号

    printf_s("请输入一个 有限不循环小数 或 无限循环小数(循环节放在括号内) :\n");
    scanf_s("%s%*c", str, MAX_SIZE);
    //分离小数的有限部分和循环部分
    for (int i = 0; i < MAX_SIZE; i++)
    {
        if (str[i] == '(')
        {
            isLeftBracket = TRUE;
            continue;
        }
        else if (str[i] == ')' || str[i] == '\0')
            break;

        if (!isLeftBracket)
        {
            finite[i]   = str[i];
            if(str[i]  != '.')
                loop[i] = '0';
            else
                loop[i] = '.';
        }
        else
        {
            finite[i - 1]   = '\0';
            loop[i - 1]     = str[i];
        }
    }

    Fraction result;

    if (!isLeftBracket) //没有括号,则是有限小数
    {
        result = FiniteDecimalToFraction(finite);
    }
    else
    {
        Fraction finiteFraction = FiniteDecimalToFraction(finite);
        Fraction infiniteFraction = InfiniteDecimalToFraction(loop);
        result = FractionAdd(finiteFraction, infiniteFraction);
    }

    PrintFraction(result);
}

int main()
{
    GetInput();

    return 0;
}

999.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-5-7 17:47:52 | 显示全部楼层    本楼为最佳答案   
工具人来了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_SIZE            1024
#define BOOL                int
#define TRUE                1
#define FALSE               0

//分数结构体
typedef struct _Fraction
{
    //分子
    int numerator;
    //分母
    int denominator;
} Fraction;

//创建分数对象
Fraction CreateFraction(int n, int d)
{
    Fraction result = { n, d };
    return result;
}

//最大公约数
int GreatestCommonDivisor(int a, int b)
{
    if (a == 1 || b == 1) return 1;
    else if (a == b) return a;

    int big     = a > b ? a : b;
    int small   = (a + b) - big;
    int t       = 0;

    while (small > 0)
    {
        t       = small;
        small   = big % small;
        big     = t;
    }

    return big;
}

//最小公倍数
int LeastCommonMultiple(int a, int b)
{
    int gcd = GreatestCommonDivisor(a, b);
    return a * b / gcd;
}

//简化分数
void SimplifyFraction(Fraction* dec)
{
    int g                = GreatestCommonDivisor(dec->numerator, dec->denominator);
    dec->numerator      /= g;
    dec->denominator    /= g;
}

//分数相加
Fraction FractionAdd(Fraction a, Fraction b)
{
    int lcm = LeastCommonMultiple(a.denominator, b.denominator);
    Fraction result = CreateFraction(a.numerator * (lcm / a.denominator) + b.numerator * (lcm / b.denominator), lcm);
    SimplifyFraction(&result);
    return result;
}

//打印分数到屏幕
void PrintFraction(Fraction a) { printf_s("当前分数为: %d/%d \n", a.numerator, a.denominator); }

//有限不循环小数转分数
Fraction FiniteDecimalToFraction(char* numStr)
{
    int n           = 0;        //分子
    int d           = 1;        //分母
    BOOL isPoint    = FALSE;    //是否遇到小数点

    for (int i = 0; i < strlen(numStr); i++)
    {
        if (numStr[i] == '.')
        {
            isPoint = TRUE;
            continue;
        }

        n = n * 10 + (numStr[i] - 0x30);

        if (isPoint)
            d = d * 10;
    }

    Fraction result = CreateFraction(n, d);
    SimplifyFraction(&result);

    return result;
}

//无限循环小数转分数
Fraction InfiniteDecimalToFraction(char* loopStr)
{
    int  ZeroAfterPoint     = 1;        //小数点后,循环节开始前0的个数
    BOOL isPoint            = FALSE;    //是否遇到小数点
    BOOL isStartLoop        = FALSE;    //循环节是否开始
    int  n                  = 0;        //分子
    int  d                  = 0;        //分母

    for (int i = 0; i < strlen(loopStr); i++)
    {
        if (loopStr[i] == '.')
        {
            isPoint = TRUE;
            continue;
        }

        if (isPoint && loopStr[i] != '0')
            isStartLoop = TRUE;

        if (isPoint && !isStartLoop)
            ZeroAfterPoint *= 10;
        else if (isPoint && isStartLoop)
        {
            n = n * 10 + (loopStr[i] - 0x30);
            d = d * 10 + 9;
        }
    }

    Fraction result = CreateFraction(n, d * ZeroAfterPoint);
    return result;
}

//输入
void GetInput()
{
    char finite[MAX_SIZE]   = { 0 };        //有限部分
    char loop[MAX_SIZE]     = { 0 };        //循环部分
    char str[MAX_SIZE]      = { 0 };        //整体
    BOOL isLeftBracket      = FALSE;        //是否遇到左括号

    printf_s("请输入一个 有限不循环小数 或 无限循环小数(循环节放在括号内) :\n");
    scanf_s("%s%*c", str, MAX_SIZE);
    //分离小数的有限部分和循环部分
    for (int i = 0; i < MAX_SIZE; i++)
    {
        if (str[i] == '(')
        {
            isLeftBracket = TRUE;
            continue;
        }
        else if (str[i] == ')' || str[i] == '\0')
            break;

        if (!isLeftBracket)
        {
            finite[i]   = str[i];
            if(str[i]  != '.')
                loop[i] = '0';
            else
                loop[i] = '.';
        }
        else
        {
            finite[i - 1]   = '\0';
            loop[i - 1]     = str[i];
        }
    }

    Fraction result;

    if (!isLeftBracket) //没有括号,则是有限小数
    {
        result = FiniteDecimalToFraction(finite);
    }
    else
    {
        Fraction finiteFraction = FiniteDecimalToFraction(finite);
        Fraction infiniteFraction = InfiniteDecimalToFraction(loop);
        result = FractionAdd(finiteFraction, infiniteFraction);
    }

    PrintFraction(result);
}

int main()
{
    GetInput();

    return 0;
}

999.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-11 14:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表