[2_4_fracdec] Repeating decimal: consider 2 & 5 in the numerator/denominator
来源:互联网 发布:京东万象数据平台 编辑:程序博客网 时间:2024/04/28 07:59
Write a program that will accept a fraction of the form N/D, where N is the numerator and D is the denominator and print the decimal representation. If the decimal representation has a repeating sequence of digits, indicate the sequence by enclosing it in brackets. For example, 1/3 = .33333333...is denoted as 0.(3), and 41/333 = 0.123123123...is denoted as 0.(123). Use xxx.0 to denote an integer. Typical conversions are:
1/3 = 0.(3)22/5 = 4.41/7 = 0.(142857)2/2 = 1.03/8 = 0.37545/56 = 0.803(571428)
PROGRAM NAME: fracdec
INPUT FORMAT
A single line with two space separated integers, N and D, 1 <= N,D <= 100000.SAMPLE INPUT (file fracdec.in)
45 56
OUTPUT FORMAT
The decimal expansion, as detailed above. If the expansion exceeds 76 characters in length, print it on multiple lines with 76 characters per line.SAMPLE OUTPUT (file fracdec.out)
0.803(571428)
Remember long division? We know that the decimal expansion is repeating when, after the decimal point, we see a remainder we've seen before. The repeating part will be all the digits we've calculated since the last time we saw that remainder.
We read in the input and print the integer part. Then we do long division on the fractional part until we see a remainder more than once or the remainder becomes zero. If we see a remainder more than once, we're repeating, in which case we print the non-repeated and repeated part appropriately. If the remainder becomes zero, we finished, in which case we print the decimal expansion. When no digits of the decimal expansion have been generated, the correct answer seems to be to print a zero.
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#define MAXDIGIT 100100char dec[MAXDIGIT];int lastrem[MAXDIGIT];char buf[MAXDIGIT];voidmain(void){ FILE *fin, *fout; int n, d, k, i, rem, len; fin = fopen("fracdec.in", "r"); fout = fopen("fracdec.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d %d", &n, &d); sprintf(buf, "%d.", n/d);/* long division keeping track of if we've seem a remainder before */ for(i=0; i<MAXDIGIT; i++)lastrem[i] = -1; rem = n % d; for(i=0;; i++) {if(rem == 0) { if(i == 0)sprintf(buf+strlen(buf), "0"); elsesprintf(buf+strlen(buf), "%s", dec); break;}if(lastrem[rem] != -1) { k = lastrem[rem]; sprintf(buf+strlen(buf), "%.*s(%s)", k, dec, dec+k); break;}lastrem[rem] = i;n = rem * 10;dec[i] = n/d + '0';rem = n%d; } /* print buf 76 chars per line */ len = strlen(buf); for(i=0; i<len; i+=76) { fprintf(fout, "%.76s\n", buf+i); } exit(0);}
Here's a another, more elegant solution from Anatoly Preygel.
Compute the number of digits before the repeat starts, and then you don't even have to store the digits or remainders, making the program use much less memory and go faster. We know that powers of 2 and 5 are the only numbers which do not result in a repeat, so to find the number of digits before the repeat, we just find the maximum of the differences between the powers of 2 and 5 in the denominator and numerator (see code snippet). Then we just use the first remainder, and output each digit as we calculate it:
#include <iostream.h>#include <fstream.h>#include <math.h>ofstream out("fracdec.out");int colcount=0;int numBeforeRepeat(int n, int d) { int c2=0, c5=0; if (n == 0) return 1; while (d%2==0) { d/=2; c2++; } while (d%5==0) { d/=5; c5++; } while (n%2==0) { n/=2; c2--; } /* can go negative */ while (n%5==0) { n/=5; c5--; } /* can go negative */ if (c2>c5) if (c2>0) return c2; else return 0; else if (c5>0) return c5; else return 0;}void print (char c) { if (colcount==76) { out<<endl; colcount=0; } out<<c; colcount++;}void print (int n) { if (n>=10) print (n/10); print ((char)('0'+(n%10)));}int main() { int n, d; ifstream in("fracdec.in"); in>>n>>d; in.close(); print (n/d); print ('.'); n=n%d; int m=numBeforeRepeat(n,d); for(int i=0;i<m;i++) { n*=10;print (n/d); n%=d; } int r=n; if(r!=0) {print ('('); do { n*=10; print (n/d); n%=d; } while (n!=r);print (')'); } out<<endl; out.close(); exit (0);}
- [2_4_fracdec] Repeating decimal: consider 2 & 5 in the numerator/denominator
- 矩阵求导——Numerator Layout & Denominator Layout
- UVa 202 Repeating Decimal
- uva 202--Repeating Decimal
- Java – Display double in 2 decimal points
- decimal.Round(decimal.Parse("0.3333333"),2)
- count the number of 1 in a decimal integer
- Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plu
- Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plu
- 习题2-5 分数化小数(decimal)
- 习题2-5 分数化小数(decimal)
- DECIMAL (6,2)
- decimal(9,2)
- Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-stand
- 98 Consider the following scenario for your database: - Backup optimization is enabled in RMAN. - Th
- Last_Error: Slave SQL thread retried transaction 10 time(s) in vain, giving up. Consider raising the
- Expression was too complex to be solved in reasonable time; consider breaking up the expression into
- Find the two non-repeating elements in an array of repeating elements
- day02基础
- 《第四周实验报告任务1》
- Redis作者谈Redis应用场景
- FLEX组件CLICK事件中带参数
- T4系列文章之1:认识T4
- [2_4_fracdec] Repeating decimal: consider 2 & 5 in the numerator/denominator
- T4系列文章之2:T4工具简介、调试以及T4运行原理
- 构造Pythonic C module
- day03基础
- 关于Map集合的遍历
- T4系列文章之3:T4语法的介绍
- 3.59
- 指针与函数1
- spring 管理action实例 scope="session"