小数化分数2-- 2007省赛集训队练习赛(2)

小数化分数
Ray在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。

输入
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
输出
对每一个对应的小数化成最简分数后输出,占一行。

样例输入
3
0.(4)
0.5
0.32(692307)
样例输出
4/9
1/2
17/52

AC代码

/*
教训:
一定要多列出几个例子,不能只列出一两个例子,容易出错,耽误时间!
解题思路:
有限小数
0.1 = 1/10;
0.2 = 2/10;
0.88 = 88/100;

循环小数
0.(1) = 1/9;
0.(123) = 123/999 = 41/333;
0.(2132) = 2132/9999;

混循环小数
0.3(4) = 3/10 + 4/90;
0.33(4) = 33/100 + 4/900; 
0.33(44) = 33/100 + 44/9900
记录,开始写错了,一定要多列出几个,当时只列出了两个混循环小数,以为第二个分母只是90,900,90000之类
没想到是9900,900,99990,之类的规律

公式
0.a(b) = a/(10^a.length) + b/(9...9*10^a..length)
此处9的数量取决于混循环小数的位数

*/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;

string num;

//求有几个9,例如参数为2则返回99
long long getNine(int size) 
{
	int n = 0;
	while (size--)
	{
		n = n * 10 + 9;
	}
	return n;
}
//求公约数
long long getYue(long long num1, long long num2)
{
	long long tmp;
	if (num1 < num2)
	{
		tmp = num1;
		num1 = num2;
		num2 = tmp;
	}
	while (num2 != 0)
	{
		tmp = num1 % num2;
		num1 = num2;
		num2 = tmp;
	}
	return num1;
}
//求公倍数
long long getBei(long long num1, long long num2)
{
	long long yue = getYue(num1, num2);
	return num1 *num2 / yue;
}

int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		string a, b;
		cin >> num;
		int i;
		for (i = 2; i < num.length(); i++)
		{
			if (num[i] != '(')
			{
				a += num[i];
			}
			else break;
		}

		for (i++; i < num.length(); i++)
		{
			if (num[i] != ')')
			{
				b += num[i];
			}
			else break;
		}
		
		//其实,有限小数,循环小数,还有混循环小数可以写在一起,这个就交给你们了!!!加油!!!朕乏了~
		if (a.length() != 0 && b.length() != 0)//a,b同时不为0的情况,最复杂
		{
			//公式 0.a(b) = a / (10 ^ a.length) + b / (9...9 * 10 ^ a..length)
			/*
			混循环小数
			0.3(4) = 3/10 + 4/90;
			0.33(4) = 33/100 + 4/900; 
			0.33(44) = 33/100 + 44/9900
			*/
			long long numA, numB;
			//字符串转换成数字
			stringstream turnA, turnB;
			turnA << a; turnA >> numA;
			turnB << b; turnB >> numB;

			long long numAF = pow(10, a.length());
			long long numBF = getNine(b.length()) * pow(10, a.length());

			//求出分母最小公倍数,方便计算两个分数的和
			long long zuiXiaoGongBeiShu = getBei(numAF, numBF);
			long long beiA = zuiXiaoGongBeiShu / numAF;
			long long beiB = zuiXiaoGongBeiShu / numBF;

			numA = beiA * numA;
			numAF = beiA *numAF;
			numB = beiB * numB;
			numBF = beiB * numBF;
			
			//两分数相加
			long long fenzi = numA + numB;
			long long fenmu = numAF;

			long long yueFenShu = getYue(fenzi, fenmu);


			cout << fenzi / yueFenShu << "/" << fenmu / yueFenShu << endl;;


		}
		else if (a.length() == 0 && b.length() != 0)
		{
			long long numB;
			stringstream turnB;
			turnB << b;
			turnB >> numB;

			long long numBF = getNine(b.length());

			long long yue = getYue(numB, numBF);
			numB = numB / yue;
			numBF = numBF / yue;
			
			cout << numB << "/" << numBF << endl;
		}
		else if (a.length() != 0 && b.length() == 0)
		{
			long long numA;
			stringstream turnA;
			turnA << a;
			turnA >> numA;

			long long numAF = pow(10, a.length());

			long long yue = getYue(numA, numAF);
			numA = numA / yue;
			numAF = numAF / yue;

			cout << numA << "/" << numAF << endl;
		}
	}
	
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章