【问题描述】
任何小数都能表示成分数的形式,对于給定的小数,编写程序其化为最简分数输出,小数包括简单小数和循环小数。
【输入形式】
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
【输出形式】
对每一个对应的小数化成最简分数后输出,占一行
【样例输入】
3
0.(4)
0.5
0.32(692307)
【样例输出】
4/9
1/2
17/52
解题思路:
对于本题的整数部分都是零的
1.对于普通不包含循环体的小数(其中有无限不循环小数), 其化为分数都是让小数点后组成的数除以10的此数的位数次方,比如0.1234=1234/10000。
2.对于无限循环小数来说,化为分数的方法就是看循环体有几位,则分母中就包含几个9,如果小数部分除循环体外还有数,则有几个数,就在分母后面加几个零。例如0.32(692307),分母就为99999900,循环体有6位所以分母有6个9,小数部分除循环体外还有两位数,则分母再加两个零即可。分子则是由小数部分包含循环体组成的数减去非循环体组成的数,例如:0.32(692307),分子为32692307-32
AC代码如下:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
int i,j,len,t1,t2,t3,t4,t5,T,flag,sum1,sum2;
char str[200];
scanf("%d",&T);
while(T--){
flag=t1=t2=t4=t5=sum1=sum2=0;
scanf("%s",str);
len=strlen(str);
for(i=2;i<len;i++){ //去掉整数部分的零和小数点,直接从小数部分也就是2开始循环
if(str[i]=='('||str[i]==')'){
flag=1;//判断是否包含循环体
}
if(flag==1&&str[i]>='0'&&str[i]<='9')
sum2++;//计算循环体的位数,方便计算分母有多少个9
if(flag==0){
t4=t4*10+str[i]-'0';//非循环体组成的整数
sum1++;//非循环体位数,方便计算在分母上添几个零
}
if(str[i]>='0'&&str[i]<='9')
t5=t5*10+str[i]-'0';//小数点后所有数组成的整数
}
if(flag==0){
for(i=2;i<len;i++){
t1=t1*10+(str[i]-'0');//没有循环体时,计算出分子
}
t2=pow(10,len-2);
t3=__gcd(t1,t2); //求出两数的最大公约数
printf("%d/%d\n",t1/t3,t2/t3);
}
else{
t1=t5-t4;//有循环体时分子的值
for(i=1;i<=sum2;i++)
t2=t2*10+9;//计算9的个数
t2=t2*pow(10,sum1);
t3=__gcd(t1,t2);
printf("%d/%d\n",t1/t3,t2/t3);
}
}
return 0;
}