ACM: 小数转分数 toj 1336
来源:互联网 发布:厦门淘宝代运营 编辑:程序博客网 时间:2024/05/16 17:10
小数化分数
描述Ray在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
输入
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
输出
对每一个对应的小数化成最简分数后输出,占一行。
样例输入
30.(4)
0.5
0.32(692307)
样例输出
4/9
1/2
17/52
题意: 任何纯小数转化为分数.
解题思路:
普通小数转为分数,分母为10的次幂即10、100、1000、10000…… 1. 一开始遇见, 毫无头绪, 小数怎么转分数.
2. 查阅资料发现:
0.1=1/10
0.2=2/10=1/5
0.34=34/100
0.987=987/1000
0.125=125/1000=1/8
12.125=12又1/8
无限循环小数转为分数,以9、99、999、9999……为分母,循环节为分子
0.3(3循环)=3/9=1/3
0.28(28循环)=28/99
0.16(6循环)=0.1+0.06(6循环)= 1/10+6/90=15/90=1/6
3. 剩下就是配合gcd处理问题.
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
#define MAX 25
char str[MAX];
char num1[MAX], num2[MAX];
int gcd(int a,int b)
{
if(b == 0) return a;
else return gcd(b,a%b);
}
void solve()
{
int len, m, length, nn, t, n1, d;
char *p;
p = strchr(str,'(');
if(p != NULL)
{
p++;
str[strlen(str)-1] = '\0'; //去除最后的')'
length = (p-str)-3; //前端不循环的长度
m = 1;
for(int i = strlen(p); i > 0; --i) m *= 10;
m--;
t = m; //9的个数
for(int i = 0; i < length; ++i) m *= 10; //循环部分转化为分数的分母
n1 = strtol(p,NULL,10); //后端循环小数
p--;
*p = '\0';
len = strlen(str);
for(p = str+2; *p; ++p)
if( (*p) != '0' )
break;
nn = strtol(p,NULL,10); //前面不循环的小数
nn *= t;
n1 += nn;
d = gcd(n1,m);
printf("%d/%d\n",n1/d,m/d);
}
else