PAT甲级(Advanced Level)练习题 Rational Sum
题目描述
Given N rational numbers in the form “numerator/denominator”, you are supposed to calculate their sum.
输入描述
Each input file contains one test case. Each case starts with a positive integer N (<=100), followed in the next line N rational numbers “a1/b1 a2/b2 …” where all the numerators and denominators are in the range of “long int”. If there is a negative number, then the sign must appear in front of the numerator.
输出描述:
For each test case, output the sum in the simplest form “integer numerator/denominator” where “integer” is the integer part of the sum, “numerator” < “denominator”, and the numerator and the denominator have no common factor. You must output only the fractional part if the integer part is 0.
输入例子:
5
2/5 4/15 1/30 -2/60 8/3
题目分析及实现
本题要实现分数的相加,分数相加考虑的是通分,寻找到最小公约数,然后分子分母同时相除即可。难点在于对字符串的分割处理,以及string和int之间的各种转换。
代码实现(C++版本)
// An highlighted block
#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <sstream>
using namespace std;
bool getSign(string str);
int getFenzi(string str);
int getFenmu(string str);
int strToint(string str);
int getfenshuIndex(string str);
int getGcd(int a,int b);
int getGcd(int a,int b){
a = abs(a);
b = abs(b);
int minab = min(a,b);
for(int i =minab ;i>=1;i--){
if(a%i==0 && b%i==0)
return i;
}
return 1;
}
bool getSign(string str){
if(str[0]=='-'){
return false;
}
return true;
}
int getFenzi(string str){
string fenzi="";
for(unsigned long i = 0; i < str.length();i++){
if(str[i] == '/'){
return strToint(fenzi);
}else{
fenzi += str[i];
}
}
return strToint(fenzi);
}
int getfenshuIndex(string str){
for(unsigned long i = 0; i < str.length();i++){
if(str[i]=='/')
return i;
}
return 0;
}
int getFenmu(string str){
int length = getfenshuIndex(str)+1;
string fenmu = "";
for(unsigned long i =length; i < str.length();i++){
fenmu += str[i];
}
return strToint(fenmu);
}
string calucute(string a, string b){
int bnum = getFenzi(a);
int anum = getFenmu(a);
int d = getFenzi(b);
int c = getFenmu(b);
int fenzi = bnum*c + anum*d;
int fenmu = anum*c;
int gcd = getGcd(fenzi,fenmu);
fenzi = fenzi /gcd;
fenmu = fenmu / gcd;
stringstream ss;
ss<<fenzi<<"/"<<fenmu;
string s1 = ss.str();
string ans = s1;
return ans;
}
int strToint(string str){
bool fuhao = getSign(str);
int ans = 0;
if(fuhao){
for(unsigned long i = 0; i<str.length();i++){
int weishu = str.length()-1 -i;
ans += (str[i] - '0') * pow(10,weishu);
}
return ans;
}else{
for(unsigned long i =1 ; i< str.length();i++){
int weishu = str.length()-i -1;
ans+= (str[i] -'0') * pow(10,weishu);
}
return -ans;
}
}
int main()
{
int n;
cin >> n;
string ans = "";
for(int i = 0; i< n; i++){
string input[n];
cin >> input[i];
if(i ==0){
ans = input[i];
}else if(input[i][0]!='0'){
ans = calucute(ans,input[i]);
}
}
int fenzi = getFenzi(ans);
int fenmu = getFenmu(ans);
if(ans == "1/1"){
cout<<"1"<<endl;
}else if(fenzi%fenmu == 0){
cout<<fenzi/fenmu<<endl;
}
else if (getFenzi(ans)>getFenmu(ans)){
int shang = fenzi / fenmu;
int shenyu = fenzi - shang * fenmu;
cout<< shang << " "<<shenyu<<"/"<<fenmu<<endl;
}else if (fenzi<fenmu){
cout<<fenzi <<"/"<<fenmu<<endl;
}
return 0;
}