1034 有理数四则运算 (20分)

43 篇文章 2 订阅

本题要求编写程序,计算 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 = In

1、解题思路

本题涉及到分数的化简、运算和输出。
(1)遇到分数问题,通常将分子分母分开处理,定义分数结构体:

struct Fraction{
//由于分数的乘法和除法的过程可能是分子或分母超过int型使用范围,所以一般情况下,分子和分母都是用long long型来存储
	long long up;//分子
	long long down;//分母
}

(2)分数问题肯定会遇到化简问题,首先是看分子、分母是否有公约数,有则约去最大公约数:

int gcd(int a,int b){
//欧几里得算法
	if(b==0) return a;//0和任意一个整数a的最大公约数都是a
	else return gcd(b,a%b);//a和b的公约数也是b和a%b的公约数
}

化简步骤:
1.若分数为负,负号必须跟着分子,分母始终为正;
2.若分子为0,令分母为1;
3.约分:求出分子的绝对值和分母的绝对值之间的最大公约数d,令分子分母同时除以d。

Fraction reduction(Fraction result){
	if(result.down<0){
		result.up=-result.up;
		result.down=-result.down;
	}else if(result.up==0){
		result.down=1;
	}else{
		int d=gcd(abs(result.up),abs(result.down));
		result.up/=d;
		result.down/=d;
	}
	return result;
}

(3)分数的四则运算可以按照数学计算方式解决,主要求计算后结果的分子和分母:

Fraction Add(Fraction a,Fraction b){//加法
	Fraction result;
	result.up=a.up*b.down+a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}
Fraction Minute(Fraction a,Fraction b){//减法
	Fraction result;
	result.up=a.up*b.down-a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}
Fraction Multi(Fraction a,Fraction b){//乘法
	Fraction result;
	result.up=a.up*b.up;
	result.down=a.down*b.down;
	return reduction(result);
} 
Fraction divide(Fraction a,Fraction b){//除法
	Fraction result;
	result.up=a.up*b.down;
	result.down=a.down*b.up;
	return reduction(result);
}

(3)分数的输出:
1.输出分数前,要先进行化简;
2.若分母为1,则说明是个正整数,直接输出即可
3.若分子的绝对值大于分母的绝对值,则分数为假分数,此时应按带分数的形式输出,整数部分为r.up/r.down,小数部分分母为r.up%r.down,分母为r.down。
4.若分数为真分数,直接输出分子和分母:

void showResult(Fraction r){
	r=reduction(r);
	if(r.up<0) printf("(");
	if(r.down==1)printf("%d",r.up);
	else if(abs(r.up)>r.down){
		printf("%d %d/%d",r.up/r.down,abs(r.up)%r.down,r.down);
	}else {
		printf("%d/%d",r.up,r.down);
	}
	if(r.up<0)printf(")");
}

根据题意,负分数前后要使用括号,分母为0,要输出Inf,代码如下:

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){//求公约数 
	if(b==0) return a;
	else return gcd(b,a%b);
}
struct Fraction{
	ll up;//分子 
	ll down;//分母 
}; 
Fraction reduction(Fraction result){
	if(result.down<0){
		result.up=-result.up;
		result.down=-result.down;
	}else if(result.up==0){
		result.down=1;
	}else{
		int d=gcd(abs(result.up),abs(result.down));
		result.up/=d;
		result.down/=d;
	}
	return result;
}
Fraction Add(Fraction a,Fraction b){
	Fraction result;
	result.up=a.up*b.down+a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}
Fraction Minute(Fraction a,Fraction b){
	Fraction result;
	result.up=a.up*b.down-a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}
Fraction Multi(Fraction a,Fraction b){
	Fraction result;
	result.up=a.up*b.up;
	result.down=a.down*b.down;
	return reduction(result);
} 
Fraction divide(Fraction a,Fraction b){
	Fraction result;
	result.up=a.up*b.down;
	result.down=a.down*b.up;
	return reduction(result);
}
void showResult(Fraction r){
	r=reduction(r);
	if(r.up<0) printf("(");
	if(r.down==1)printf("%d",r.up);
	else if(abs(r.up)>r.down){
		printf("%d %d/%d",r.up/r.down,abs(r.up)%r.down,r.down);
	}else {
		printf("%d/%d",r.up,r.down);
	}
	if(r.up<0)printf(")");
}
int main(){
	Fraction a,b;
	scanf("%lld/%lld %lld/%lld",&a.up,&a.down,&b.up,&b.down);
	//和
	showResult(a);
	printf(" + ");
	showResult(b);
	printf(" = ");
	showResult(Add(a,b)); 
	printf("\n");
	//差
	showResult(a);
	printf(" - ");
	showResult(b);
	printf(" = ");
	showResult(Minute(a,b)); 
	printf("\n");
	//积
	showResult(a);
	printf(" * ");
	showResult(b);
	printf(" = ");
	showResult(Multi(a,b)); 
	printf("\n");
	//商
	showResult(a);
	printf(" / ");
	showResult(b);
	printf(" = ");
	if(b.up==0)printf("Inf");
	else {
		showResult(divide(a,b));  
	}
	return 0;
}

2、总结

1、初次接触涉及分数的题目,知识点掌握得不是很全面,上面列出的关于分数的代码可以在任何涉及分数的题目中套用。
2、分数除法中,判断除数是否为0,只需要判断除数的分子是否为0。
3、由于分数的乘法和除法的过程可能是分子或分母超过int型使用范围,所以一般情况下,分子和分母都是用long long型来存储。
4、判断分子是否大于分母时,一定要使用分子的绝对值,应为分母一直为整数,而分子可能为负数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值