PAT 1034 有理数四则运算(20)
2015-02-25 23:07
211 查看
题目
/* 1034. 有理数四则运算(20) 本题要求编写程序,计算2个有理数的和、差、积、商。 输入格式: 输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。 输出格式: 分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。 输入样例1: 2/3 -4/2 输出样例1: 2/3 + (-2) = (-1 1/3) 2/3 - (-2) = 2 2/3 2/3 * (-2) = (-1 1/3) 2/3 / (-2) = (-1/3) 输入样例2: 5/3 0/6 输出样例2: 1 2/3 + 0 = 1 2/3 1 2/3 - 0 = 1 2/3 1 2/3 * 0 = 0 1 2/3 / 0 = Inf */
思路
// 1/2 + 4/5 = // 如何把一个数化为最简分数? // ::先化为真分数,再分子与分母的最大公约数 // 如何进行分数运算? // ::分母通分(求最小公倍数),分子加成
代码
#include <iostream> #include <stdio.h> using namespace std; long long maxCommon(long long a, long long b){ if(b == 0) return a; else return maxCommon(b, a%b); } struct DivNum{ bool positive; bool extInt; bool extDiv; long long int integer; //整数部分 long long int divChild; long long int divMum; bool isSimple;//是否已经化简 DivNum(){ positive = false; extInt = false; extDiv = false; integer = 0; divChild = 0; divMum = 0; isSimple = false; } void in(char * str){ string num = str; if(str[0] == '-'){ num.erase(0,1); }else{ positive = true; } sscanf(num.c_str(),"%lld/%lld", &divChild, &divMum); } void simplify(){ if(divMum == 0)return; // 分子为0 if(divChild == 0) { extInt = true; extDiv = false; integer = 0; positive = true; return; } extDiv = true; // 假分数 if(divChild >= divMum){ extInt = true; integer = divChild / divMum; divChild = divChild % divMum; // if(divChild == 0) extDiv = false; } // 化为最简真分数 long long common = maxCommon(divChild, divMum); if(common == 0) return; divChild /= common; divMum /= common; } friend DivNum operator +(const DivNum &a, const DivNum &b){ DivNum res; // 一正一副,相加==相减,结果为符号 // 正正或者负负,符号不变, if(!a.positive == b.positive){ res.divChild = a.divChild*b.divMum - b.divChild*a.divMum; res.positive = res.divChild < 0 ? !a.positive:a.positive; // 正+负-》得负,符号为负,负+正-》得负,符号为正 if(res.divChild < 0) res.divChild = -res.divChild; if(res.divChild == 0) res.positive = true; }else{ res.positive = a.positive; res.divChild = a.divChild*b.divMum + b.divChild*a.divMum; } res.divMum = a.divMum * b.divMum; return res; } void reversePositive(){positive = !positive;} friend DivNum operator -(DivNum const &a, DivNum const &b){ // a-b = a + (-b) DivNum c = b; c.reversePositive(); return a + c; } friend DivNum operator *(const DivNum &a,const DivNum &b){ DivNum res; res.positive = (a.positive && b.positive)||(!a.positive && !b.positive); // 正正得正,负负得正 res.divChild = a.divChild * b.divChild; res.divMum = a.divMum * b.divMum; if(res.divChild == 0) res.positive = true; return res; } friend DivNum operator /(const DivNum &a, const DivNum &b){ DivNum res; res.positive = (a.positive && b.positive)||(!a.positive && !b.positive); // 正正得正,负负得正 res.divChild = a.divChild * b.divMum; res.divMum = a.divMum * b.divChild; if(res.divChild == 0) res.positive = true; return res; } void out(){ if(!isSimple){ simplify(); isSimple =true; } if(divMum){ // 分母不为0 if(!positive) cout << "(-"; if(extInt) cout << integer; if(extInt && extDiv) cout << " "; if(extDiv) cout << divChild << "/" << divMum; if(!positive) cout << ")"; }else{ cout << "Inf"; } } }; int main(){ // 得到两个数字 char str1[30],str2[30]; scanf("%s%s",str1,str2); DivNum a,b; a.in(str1); b.in(str2); DivNum res[4]; char op[4]={'+','-','*','/'}; res[0] = a+b; res[1] = a-b; res[2] = a*b; res[3] = a/b; for (int i = 0; i < 4; ++i) { a.out();cout << " " << op[i] << " ";b.out();cout << " = ";res[i].out();cout << endl; } // 化为最简分数保存起来 // 进行四则运算得到四个结果 // 输出 return 0; }
过程资料
点评:这道题目比较繁琐,涉及的点比较多,坑点也多,写起来比较蛋疼。
测试点:
第3、4个测试点用的是较大数字,如果仅仅用 int 整数的, 可能会导致预料外的错误,例如第4个测试点出现了浮点错误。解决方法是改为 long long。
相关文章推荐
- 1034. 有理数四则运算(20) PAT
- PAT (Basic Level) Practise (中文)1034. 有理数四则运算(20) C语言
- PAT1034有理数四则运算(20)
- PAT乙级1034. 有理数四则运算(20)
- PAT(basic level) 1034 有理数四则运算(20)
- PAT乙级.1034. 有理数四则运算(20)
- PAT 1034. 有理数四则运算(20)
- PAT乙级 1034. 有理数四则运算(20)
- PAT-乙级-1034. 有理数四则运算(20)
- PAT-B 1034. 有理数四则运算(20)
- PAT : 1034. 有理数四则运算(20)
- 1034. 有理数四则运算(20)PAT乙级&&1088. Rational Arithmetic (20)PAT甲级
- 【再思考】PATBasic——1034. 有理数四则运算(20)
- PAT (Basic Level) Practise (中文)1034. 有理数四则运算(20)
- PAT乙级1034. 有理数四则运算(20)
- PAT(A) 1088. Rational Arithmetic & PAT(B) 1034. 有理数四则运算(20)
- PAT-乙级-1034. 有理数四则运算(20)
- 1034. 有理数四则运算(20)-浙大PAT乙级真题java实现
- pat乙级1034. 有理数四则运算(20)
- PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20)