这是以前帮一个哥们做的考研复试题,还是比较有趣的。
首先输入测试数据组数,然后每一组输入的格式为a.b(c),比如:
10 3.1(3) 0.(3) 1.(25)
输出分数形式:
47/15 1/3 124/99
代码和分析如下:
#include <stdio.h> #include <string.h> //按照题目条件,设小数是a.b(c)的,比如3.1(3)但是有可能b是空串,比如0.(10) //思路,拿3.1(3)举例:x = 3.1(3) ; 10x = 31.(3) ; 100x = 313.(3) ; => 90x = 313.(3) - 31.(3) ,循环节将就这样消去了 void extract(char *str, int *pb, int *pc) { char *p = str; *pb = *pc = 0; if (*p != ‘(‘) //能得到b { do { *pb = *pb * 10 + *p++ - ‘0‘; } while (*p != ‘(‘);//直到遇到左括号,说明b读完了 } else //得不到b,只能得到c { *pb = -1;//用-1表示b读取失败 } p++;//跳过左括号 do { *pc = *pc * 10 + *p++ - ‘0‘; } while (*p != ‘)‘);//同理取出c,到右括号为止 } int gcd(int a, int b)//最大公约数 { if (!b) return a; else return gcd(b, a%b); } int pow10(int x)//10的x次方 { int result = 1; while (x--) result *= 10; return result; } int main(void) { int n; int a, b, c; int M, N, gcd_m_n; //最后结果表示为N/M,因为要化成最简分数所以用gcd_m_n约分 char buf[16]; scanf("%d", &n); while (n--) { scanf("%d.", &a);//一定有a,把a和小数点取出,注意是"%d."不是"%d" scanf("%s", buf);//剩下的放入缓冲区 extract(buf, &b, &c); // /*测试输入3.1(4) 3.(4)是否识别*/ printf("%d %d %d", a, b, c); if (b == -1) { int c_mul; char c_buf[16]; sprintf(c_buf, "%d", c); c_mul = pow10(strlen(c_buf)); N = c_mul - 1; M = a * c_mul + c - a; gcd_m_n = gcd(M, N); M /= gcd_m_n; N /= gcd_m_n; printf("%d/%d\n", M, N); } else { int b_mul, c_mul; char b_buf[16]; char c_buf[16]; sprintf(b_buf, "%d", b); sprintf(c_buf, "%d", c); b_mul = pow10(strlen(b_buf)); c_mul = pow10(strlen(c_buf)); N = c_mul * b_mul - b_mul; M = a * b_mul * c_mul + b * c_mul + c - a * b_mul - b; gcd_m_n = gcd(M, N); M /= gcd_m_n; N /= gcd_m_n; printf("%d/%d\n", M, N); } } return 0; }
时间: 2024-09-30 14:37:00