与琪热恋 发表于 2021-5-1 19:45:43

Decimal or Fractional

小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
求大佬看看孩子吧,是真的没思路

yuxijian2020 发表于 2021-5-7 17:47:52

工具人来了{:10_266:}

#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 == '.')
      {
            isPoint = TRUE;
            continue;
      }

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

      if (isPoint)
            d = d * 10;
    }

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

    return result;
}

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

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

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

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

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

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

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

      if (!isLeftBracket)
      {
            finite   = str;
            if(str!= '.')
                loop = '0';
            else
                loop = '.';
      }
      else
      {
            finite   = '\0';
            loop   = str;
      }
    }

    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;
}


页: [1]
查看完整版本: Decimal or Fractional