N个数求和(c++)

题目要求

本题的要求很简单,就是求N个数字的和。
麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:

输入第一行给出一个正整数N(≤100)。
随后一行按格式a1/b1 a2/b2…给出N个有理数。
题目保证所有分子和分母都在长整型范围内。
另外,负数的符号一定出现在分子前面。

输出格式:

输出上述数字和的最简形式 —— 即将结果写成整数部分
分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

输入样例1:

5
2/5 4/15 1/30 -2/60 8/3

输出样例1:

3 1/3

输入样例2:

2
4/3 2/3

输出样例2:

2

输入样例3:

3
1/3 -1/6 1/8

输出样例3:

7/24

做这道题时也是绕了很多弯路,一开始的想法相当的麻烦,但是有办法总比没办法好。于是,我就按照自己的思路:输入的分数,我是按字符串读取的,每两个字符串处理之后(处理为分子1,分母1,分子2,分母2,其实就是把数字从字符串中截取出来),相加,得到一个分数。然后判断这个分子的绝对值是否大于分母。如果大的话,就取整(取得的整数为全局变量)再求分数部分。最后是把分数约分化简(我约分化简了两次,怕没化到最简)。在这个字符串相加函数最后返回分数字符串。在主函数中,
string x = add(data[0],data[1]);
for(int i=2;i<N;i++){
x = add(x,data[i]);
}
。要说明一下,我设了一个全局的整数、分子、分母。(可能也没多大用吧,但是也不想改了)。
代码如下:

#include<iostream>
#include<sstream>
#include<cmath>
#include<string>
using namespace std;

long int zhengshu,fenzi,fenmu;


string add(string s1,string s2){
	long int a,b,c,d;long int temp;stringstream ss;
	temp = s1.find_first_of('/',0);
	
	ss<<s1.substr(0,temp);
	ss>>a;
	ss.clear();
	ss<<s1.substr(temp+1,s1.length()-temp-1); 
	ss>>b;
	
	ss.clear();
	temp = s2.find_first_of('/',0);
	ss<<s2.substr(0,temp);
	ss>>c;
	ss.clear();
	ss<<s2.substr(temp+1,s2.length()-temp-1);
	ss>>d;
	
	long int fenzi1,fenmu1;
	fenzi1 = a*d + c*b;
	fenmu1 = b*d;
	
	if(abs(fenzi1)> fenmu1){
		zhengshu += fenzi1/fenmu1;
		fenzi1 = fenzi1 - (fenzi1/fenmu1)*fenmu1;
		
	}else if(fenzi1 == fenmu1){
		zhengshu += 1;
		fenzi1 = 0;
		fenmu1 = 1;
	}else if((fenzi1 + fenmu1) == 0){
		zhengshu -= 1;
		fenzi1 = 0;
		fenmu1 = 1;
	}
	int k = 0;
	if(fenzi1 < 0){
		k = 1;
		fenzi1 = abs(fenzi1);
	}
	//约分 化简 
	for(int i=2;i<=fenzi1;i++){
		if(fenzi1%i==0 && fenmu1%i==0){
			fenzi1 = fenzi1/i;
			fenmu1 = fenmu1/i;
		}
	}
	
	for(int i=2;i<=fenzi1;i++){
		if(fenzi1%i==0 && fenmu1%i==0){
			fenzi1 = fenzi1/i;
			fenmu1 = fenmu1/i;
		}
	}
	if(k == 1) fenzi1 = -fenzi1;
	fenmu = fenmu1;
	fenzi = fenzi1;
	ss.clear();
	string m;
	ss<<fenzi;
	ss>>m;
	ss.clear();
	string n;
	ss<<fenmu;
	ss>>n;
	return m+"/"+n;
}

int main(){
	int N;
	cin>>N;
	string data[N];
	for(int i=0;i<N;i++){
		cin>>data[i];
	}

	string x = add(data[0],data[1]);
	for(int i=2;i<N;i++){
		x = add(x,data[i]);
	}
	if(fenzi == 0)
		cout<<zhengshu;
	else if(zhengshu == 0)
		cout<<fenzi<<"/"<<fenmu;
	else
		if(zhengshu > 0 && fenzi < 0){
			if(zhengshu-1 != 0)
				cout<<zhengshu-1<<" "<<fenzi + fenmu<<"/"<<fenmu;
			else
				cout<<fenzi + fenmu<<"/"<<fenmu;
		} 
		else if(zhengshu < 0 && fenzi > 0)
			if(zhengshu+1 != 0)
				cout<<zhengshu+1<<" "<<fenmu-fenzi<<"/"<<fenmu;
			else
				cout<<fenmu-fenzi<<"/"<<fenmu;
		else
			cout<<zhengshu<<" "<<abs(fenzi)<<"/"<<fenmu;
	return 0;
}

因为,我的整数部分和分数部分是分开计算的,所以会有,整数为正,分数为负;整数为负,分数为整的情况QwQ(改了超级久,才发现,我太难了)。
但是,我看了别人的代码之后,才知道自己的代码有多垃圾QwQ。如下,是我按照别人的思路打的代码。

#include<iostream>
#include<cmath>
using namespace std;

struct Node{
	long int zi;
	long int mu;
}data;

//最大公因数
int Max(int a,int b){
	int small = min(a,b);
	int big = max(a,b);
	int temp;
	if(big%small == 0)return small;
	while(big%small){
		temp = big%small;
		big = small;
		small = temp;
	}
	return small;
} 

//最小公倍数
int Min(int a,int b){
	return a*b/Max(a,b);
} 

int main(){
	int N;
	cin>>N;
	Node n[N];
	char c;
	for(int i=0;i<N;i++){
		cin>>n[i].zi>>c>>n[i].mu;
	}
	//分母最小公倍数
	int min = n[0].mu;
	for(int i=1;i<N;i++){
		min = Min(min,n[i].mu);
	}
	int sum = 0;
	//所有分子的 和
	for(int i=0;i<N;i++){
		sum += n[i].zi*min/n[i].mu;
	}
	if(sum < 0){
		cout<<"-";
	}
	if(sum == 0){
		cout<<0;
		return 0;
	}
	sum = abs(sum);
	int max = Max(sum,min);
	sum /= max;
	min /= max;
	if(sum >= min){
		if(sum - (sum/min)*min != 0)
			cout<<sum/min<<" "<<(sum - (sum/min)*min)<<"/"<<min<<endl;
		else
			cout<<sum/min;
	}
	else{
		cout<<sum<<"/"<<min;
	}
	return 0;
}

只要多练习,思路就会变得和大佬一样。

一个集坚强与自信于一身的菇凉。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡雅的惆怅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值