HNU程序设计-小数化分数

一.问题描述

二.问题分析及思路

小数化分数:

1.对于不循环小数,小数点后有i位,则分子为这i位数,分母为10i次方,约分得到最简分数(除最大公约数)

2.对于只有循环的小数,分子为循环的部分(i位),分母为i9,如0.436=436/999

3.对于混合型,分子为所有数字减去非循环部分(i位),如0.32692307)的分子为32692307-32,分母为循环数字个9加非循环数字个00.32692307)的分母为6920,即99999900

原理是不循环部分保留,循环部分按等比数列求和,可以自己推算一下。

实现

1.去掉前两位0.,如果接下来第一位为(,则按循环型处理,pow函数按位把字符转化为数字

2.使用find函数,如果不含‘(’,按不循环小数处理,pow函数按位把字符转化为数字

3.最后一种情况为混合型,需要记录不循环的数字个数s1,循环的数字个数s2,用flag判断是哪个部分,遇到‘(’,flag=1,开始记录循环部分,同时直接求所有数字构成的数,遍历完后,根据s1s2减去不循环的数字,并计算分母

三.代码

#include<iostream>
#include<string.h>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
	if(a%b==0) return b;
	else return gcd(b,a%b);
}
string f(string a)
{
    a.erase(0,2);
    string res="";
    int len=a.length();
    if(a[0]=='(')
    {
    	int x=0,y=0;
		for(int i=1;i<len-1;i++) {x+=(a[i]-'0')*pow(10,len-i-2);y+=pow(10,len-i-2)*9;}
		res+=to_string(x/gcd(x,y))+"/"+to_string(y/gcd(x,y));
		return res;
	}
	else if(a.find('(')==string::npos)
	{
		int x=0,y=1;
		for(int i=0;i<len;i++) {x+=(a[i]-'0')*pow(10,len-i-1);y*=10;}
		res+=to_string(x/gcd(x,y))+"/"+to_string(y/gcd(x,y));
		return res;
	}
	else
	{
		int x=0,y=0,s1=0,s2=0,flag=0;
		for(int i=0;i<len-1;i++)											//到len-1,不取)
		{
			if(a[i]!='('&&flag==0) {s1++;x+=(a[i]-'0')*pow(10,len-i-3);}
			else if(a[i]=='(') flag=1;
			else if(flag==1) {s2++;x+=(a[i]-'0')*pow(10,len-i-2);}
		}
		for(int i=0;i<s2;i++) y+=9*pow(10,s2-i-1);
		for(int i=0;i<s1;i++) {x-=(a[i]-'0')*pow(10,s1-1-i);y*=10;}
		res+=to_string(x/gcd(x,y))+"/"+to_string(y/gcd(x,y));
		return res;
	}
}
int main()
{
	string x;
	int t;
	cin>>t;
	for(int i=0;i<t;i++)
	{	
		cin>>x;
		cout<<f(x)<<endl;
	}
	return 1;
}

最近事情多时间有点紧,解题都是倾向无脑直接写,写的可能会有点不清楚。。。.这道题只要知道小数转分数的原理,对着下标把字符转成需要的数字计算就可以,具体的下标和数字转化最好还是自己写一下。

Guess you like

Origin blog.csdn.net/Aaron503/article/details/121537165