鱼C论坛

 找回密码
 立即注册
查看: 1611|回复: 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
工具人来了

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>

  5. #define MAX_SIZE            1024
  6. #define BOOL                int
  7. #define TRUE                1
  8. #define FALSE               0

  9. //分数结构体
  10. typedef struct _Fraction
  11. {
  12.     //分子
  13.     int numerator;
  14.     //分母
  15.     int denominator;
  16. } Fraction;

  17. //创建分数对象
  18. Fraction CreateFraction(int n, int d)
  19. {
  20.     Fraction result = { n, d };
  21.     return result;
  22. }

  23. //最大公约数
  24. int GreatestCommonDivisor(int a, int b)
  25. {
  26.     if (a == 1 || b == 1) return 1;
  27.     else if (a == b) return a;

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

  31.     while (small > 0)
  32.     {
  33.         t       = small;
  34.         small   = big % small;
  35.         big     = t;
  36.     }

  37.     return big;
  38. }

  39. //最小公倍数
  40. int LeastCommonMultiple(int a, int b)
  41. {
  42.     int gcd = GreatestCommonDivisor(a, b);
  43.     return a * b / gcd;
  44. }

  45. //简化分数
  46. void SimplifyFraction(Fraction* dec)
  47. {
  48.     int g                = GreatestCommonDivisor(dec->numerator, dec->denominator);
  49.     dec->numerator      /= g;
  50.     dec->denominator    /= g;
  51. }

  52. //分数相加
  53. Fraction FractionAdd(Fraction a, Fraction b)
  54. {
  55.     int lcm = LeastCommonMultiple(a.denominator, b.denominator);
  56.     Fraction result = CreateFraction(a.numerator * (lcm / a.denominator) + b.numerator * (lcm / b.denominator), lcm);
  57.     SimplifyFraction(&result);
  58.     return result;
  59. }

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

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

  68.     for (int i = 0; i < strlen(numStr); i++)
  69.     {
  70.         if (numStr[i] == '.')
  71.         {
  72.             isPoint = TRUE;
  73.             continue;
  74.         }

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

  76.         if (isPoint)
  77.             d = d * 10;
  78.     }

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

  81.     return result;
  82. }

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

  91.     for (int i = 0; i < strlen(loopStr); i++)
  92.     {
  93.         if (loopStr[i] == '.')
  94.         {
  95.             isPoint = TRUE;
  96.             continue;
  97.         }

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

  100.         if (isPoint && !isStartLoop)
  101.             ZeroAfterPoint *= 10;
  102.         else if (isPoint && isStartLoop)
  103.         {
  104.             n = n * 10 + (loopStr[i] - 0x30);
  105.             d = d * 10 + 9;
  106.         }
  107.     }

  108.     Fraction result = CreateFraction(n, d * ZeroAfterPoint);
  109.     return result;
  110. }

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

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

  130.         if (!isLeftBracket)
  131.         {
  132.             finite[i]   = str[i];
  133.             if(str[i]  != '.')
  134.                 loop[i] = '0';
  135.             else
  136.                 loop[i] = '.';
  137.         }
  138.         else
  139.         {
  140.             finite[i - 1]   = '\0';
  141.             loop[i - 1]     = str[i];
  142.         }
  143.     }

  144.     Fraction result;

  145.     if (!isLeftBracket) //没有括号,则是有限小数
  146.     {
  147.         result = FiniteDecimalToFraction(finite);
  148.     }
  149.     else
  150.     {
  151.         Fraction finiteFraction = FiniteDecimalToFraction(finite);
  152.         Fraction infiniteFraction = InfiniteDecimalToFraction(loop);
  153.         result = FractionAdd(finiteFraction, infiniteFraction);
  154.     }

  155.     PrintFraction(result);
  156. }

  157. int main()
  158. {
  159.     GetInput();

  160.     return 0;
  161. }
复制代码


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

使用道具 举报

发表于 2021-5-7 17:47:52 | 显示全部楼层    本楼为最佳答案   
工具人来了

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>

  5. #define MAX_SIZE            1024
  6. #define BOOL                int
  7. #define TRUE                1
  8. #define FALSE               0

  9. //分数结构体
  10. typedef struct _Fraction
  11. {
  12.     //分子
  13.     int numerator;
  14.     //分母
  15.     int denominator;
  16. } Fraction;

  17. //创建分数对象
  18. Fraction CreateFraction(int n, int d)
  19. {
  20.     Fraction result = { n, d };
  21.     return result;
  22. }

  23. //最大公约数
  24. int GreatestCommonDivisor(int a, int b)
  25. {
  26.     if (a == 1 || b == 1) return 1;
  27.     else if (a == b) return a;

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

  31.     while (small > 0)
  32.     {
  33.         t       = small;
  34.         small   = big % small;
  35.         big     = t;
  36.     }

  37.     return big;
  38. }

  39. //最小公倍数
  40. int LeastCommonMultiple(int a, int b)
  41. {
  42.     int gcd = GreatestCommonDivisor(a, b);
  43.     return a * b / gcd;
  44. }

  45. //简化分数
  46. void SimplifyFraction(Fraction* dec)
  47. {
  48.     int g                = GreatestCommonDivisor(dec->numerator, dec->denominator);
  49.     dec->numerator      /= g;
  50.     dec->denominator    /= g;
  51. }

  52. //分数相加
  53. Fraction FractionAdd(Fraction a, Fraction b)
  54. {
  55.     int lcm = LeastCommonMultiple(a.denominator, b.denominator);
  56.     Fraction result = CreateFraction(a.numerator * (lcm / a.denominator) + b.numerator * (lcm / b.denominator), lcm);
  57.     SimplifyFraction(&result);
  58.     return result;
  59. }

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

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

  68.     for (int i = 0; i < strlen(numStr); i++)
  69.     {
  70.         if (numStr[i] == '.')
  71.         {
  72.             isPoint = TRUE;
  73.             continue;
  74.         }

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

  76.         if (isPoint)
  77.             d = d * 10;
  78.     }

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

  81.     return result;
  82. }

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

  91.     for (int i = 0; i < strlen(loopStr); i++)
  92.     {
  93.         if (loopStr[i] == '.')
  94.         {
  95.             isPoint = TRUE;
  96.             continue;
  97.         }

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

  100.         if (isPoint && !isStartLoop)
  101.             ZeroAfterPoint *= 10;
  102.         else if (isPoint && isStartLoop)
  103.         {
  104.             n = n * 10 + (loopStr[i] - 0x30);
  105.             d = d * 10 + 9;
  106.         }
  107.     }

  108.     Fraction result = CreateFraction(n, d * ZeroAfterPoint);
  109.     return result;
  110. }

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

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

  130.         if (!isLeftBracket)
  131.         {
  132.             finite[i]   = str[i];
  133.             if(str[i]  != '.')
  134.                 loop[i] = '0';
  135.             else
  136.                 loop[i] = '.';
  137.         }
  138.         else
  139.         {
  140.             finite[i - 1]   = '\0';
  141.             loop[i - 1]     = str[i];
  142.         }
  143.     }

  144.     Fraction result;

  145.     if (!isLeftBracket) //没有括号,则是有限小数
  146.     {
  147.         result = FiniteDecimalToFraction(finite);
  148.     }
  149.     else
  150.     {
  151.         Fraction finiteFraction = FiniteDecimalToFraction(finite);
  152.         Fraction infiniteFraction = InfiniteDecimalToFraction(loop);
  153.         result = FractionAdd(finiteFraction, infiniteFraction);
  154.     }

  155.     PrintFraction(result);
  156. }

  157. int main()
  158. {
  159.     GetInput();

  160.     return 0;
  161. }
复制代码


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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 22:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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