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
求大佬看看孩子吧,是真的没思路 工具人来了{: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]