小数化分数(C++ 代码讲解很详细)

【问题描述】
任何小数都能表示成分数的形式,对于給定的小数,编写程序其化为最简分数输出,小数包括简单小数和循环小数。
【输入形式】
第一行是一个整数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;
} 

猜你喜欢

转载自blog.csdn.net/weixin_44313771/article/details/108902477