HDU1717--小数化分数2

这道题是将输入的小数(有可能是无限循环小数)来化为分数,刚开始看到以为枚举(千万不要嘲笑我),但是感觉不对,

所以百度了小数化为分数的方法,然后看到了各种方法,原来是这这样,在这我采用的是小数化为分数的套公式法


      纯循环

用9做分母,有多少个循环数就几个9,比如0.3,3的循环就是9分之3,0.654,654的循环就是999分之654, 0.9,9的循环就是9分之9(1),以此类推。

混循环
先来看几个例子
例:把混循环小数0.228˙化为分数:
解:0.228˙
=[(228/1000)+8/9000)]
=228/(900+100)+8/9000
=[(228/900)-(228/9000)]+(8/9000)
=(228/900)+[(8/9000)-(228/9000)]
=(228/900)-(22/900)
=(228-22)/900
=206/900
=103/450;
例:把混循环小数0.123˙68˙化成分数:
解:0.123˙68˙=(0.12368+0.00000˙68˙)
=(12368/100000)+(68/9900000)
=[(12368/99000)-(12368/990000)]+(68/9900000)
=(12368/99000)+[(68/9900000)-(12368/9900000)]
=(12368/99000)-(12300/9900000)
=(12368-123)/99000
公式
用9和0做分母,首先有几个循环节就几个9,接着有几个没加入循环的数就加几个0,再用小数点后面的数减 没加入循环的数,比如0.43,3的循环,有一位数没加入循环,就在9后面加一个0做分母,再用43减4做分子,得 90分之39,0.145,5的循环就用9后面加2个0做分母,再用145减14做分子,得900分之131,0.549,49的循环,就 用99后面加1个0做分母,用549减5做分子,最后得990分之545,以此类推,能约分的要化简。

看过上面的觉得大家就知道怎么将各种小数转换为分数的方法了

然后就是代码实现了,如果理解了上面的方法,其实剩下的就是字符串的处理,最后大家不要忘就是化简得到的分数就可以了,化简其实就是求分子和分母的最大公约数,处理后进行转换就OK了哈!

贴一下自己的代码哈!

#include <iostream>
#include <string>
using namespace std;
//求最大公约数
int gcd(int a , int b)
{
	int t;
	if(a < b)
	{
		t = a;
		a = b;
		b = t;
	}
	while(b > 0)
	{
		t = b;
		b = a%b;
		a = t;
	}
	return a;
}
int main()
{
#ifdef LOCAL
	freopen("input.txt" , "r" , stdin);
#endif
	int T;
	cin >> T;
	string str;
	while(T--)
	{
		cin >> str;
		int primLength = 0 , lastLength = 0 , primValue = 0 , lastValue = 0;
		bool flag = false;
		int fenzi = 1 , fenmu = 1;
		//处理输入的小数字符串
		for(int i=2; i<str.length(); ++i)
		{
			//标记遇到左括号
			if(str[i] == '(')
			{
				flag = true;
			}
			//遇到数字后的处理
			if(str[i] >= '0' && str[i] <= '9')
			{
				if(flag)
				{
					lastLength++;
					lastValue = lastValue * 10 + (str[i] - '0');
				}else{
					primLength++;
					primValue = primValue * 10 + (str[i] - '0');
				}
			}
		}
		//对无限循环的和不循环的分别处理
		if(flag)
		{
			int temp = primValue;
			int sum = 0;
			while(lastLength--)
			{
				temp = temp * 10;
				sum = sum*10 + 9;
			}
			fenzi = temp + lastValue - primValue;
			fenmu = sum;
			while(primLength--)
			{
				fenmu = fenmu * 10;
			}
			//进行输出
			cout << fenzi/gcd(fenzi , fenmu) << "/" << fenmu/gcd(fenzi , fenmu) << endl;
		}else{
			while(primLength--)
			{
				fenmu*=10;
			}
			//进行输出
			cout << primValue/gcd(fenmu , primValue) << "/" << fenmu/gcd(fenmu , primValue) << endl;
		}
	}
	return 0;
}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值