原题描述
Problem Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
Output
对每一个对应的小数化成最简分数后输出,占一行。
Sample Input
3
0.(4)
0.5
0.32(692307)
Sample Output
4/9
1/2
17/52
解题思路
将混循环小数改写成分数,分子是不循环部分与第一个循环节连成的数字组成的数,减去不循环部分数字组成的数之差;分母的头几位数字是9,末几位数字是0,9的个数跟循环节的数位相同,0的个数跟不循环部分的数位相同.
参考代码
#include <iostream>
#include <string>
using namespace std;
int gcd(int a,int b)
{
int temp;
if (a < b)
{
temp = a;
a = b;
b = temp;
}
do
{
temp = a % b;
a = b;
b = temp;
} while (temp != 0);
return a;
}
void simplify(int & a,int & b)
{
int GCD = gcd(b, a);
a /= GCD;
b /= GCD;
}
int sum(int x,int n) // x^n
{
int s = 1;
for (int i = 0; i < n; i++)
{
s *= x;
}
return s;
}
int main()
{
int T, d1, d2, i, cir, dec; // cir循环节 dec小数部分 d1小数部分位数 d2循环节位数
string str;
cin >> T;
while(T--)
{
cin >> str;
d1 = d2 = cir = dec = 0;
// 接收并处理数据
for (i = 2; i < str.length();i++)
{
if(str[i] == '(')
{
i++;
while(str[i]!=')')
{
d2++;
cir *= 10;
cir += str[i] - '0';
i++;
}
}
else
{
d1++;
dec *= 10;
dec += str[i] - '0';
}
}
// 如果没有循环节
if(cir == 0)
{
int denominator = sum(10, d1); // 分母
simplify(dec, denominator);
cout << dec << '/' << denominator << endl;
}
// 如果有循环节
else
{
int numerator = dec * sum(10, d2) + cir - dec; // 分子
int denominator = (sum(10, d2) - 1) * sum(10, d1); // 分母
simplify(numerator, denominator);
cout << numerator << '/' << denominator << endl;
}
}
}