PAT乙级——1034(模拟四则运算)

本文详细解析了一个关于有理数四则运算的编程题目,包括加、减、乘、除的处理方法,特别强调了分数的最简形式及除法运算的特殊处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:有理数四则运算 (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

题目分析

首先这个题目是模拟四则运算,有很多的小细节需要考虑,首先是给出的分数需要显示正负,正负显示不同,显示整数和分数部分。
这个题目需要对分数的四则运算很清楚,同时,由于是分数的操作,则除法的运算是本题的核心。做了好久,想不出完美的解决办法,借鉴了网上的代码,并给出了完整的注释。

import java.util.Scanner;
 
public class Y1034 {
 
	public static void main(String[] args) {
 
		Scanner in = new Scanner(System.in);
		String[] input = in.nextLine().split("[\\s/]");
		in.close();
		//分离出数据
		long a1 = Integer.parseInt(input[0]);
		long b1 = Integer.parseInt(input[1]);
		long a2 = Integer.parseInt(input[2]);
		long b2 = Integer.parseInt(input[3]);
 
		//分母不为零,题目说了不能为零,在我看来可以不用写这个判断,可以删去此处if语句
		if (b1 != 0 && b2 != 0) {
			add(a1, b1, a2, b2);
			minus(a1, b1, a2, b2);
			mutilply(a1, b1, a2, b2);
			divide(a1, b1, a2, b2);
		}
	}
 
	//判断分子分母计算后的大小和正负,也可以当做是除法操作
	public static void tackle(long a, long b) {
		if (a == 0) {
			//若分子为零,直接输出0
			System.out.print(0);
			return;
		}
 
		//若分子小于零,则数值小于零,打印左括号和-号
		boolean isMinus = a > 0 ? false : true;
		if (isMinus) {
			System.out.print("(-");
			a = -a;//改值
		}
 
		long gcd = getGcd(a, b);//最大公约数
		a = a / gcd;//约分操作
		b = b / gcd;
		if (a % b == 0) {
			System.out.print(a / b);//无余数,输出整数
		} else if (Math.abs(a) > b) {//a的绝对值大,则一定存在整数部
			System.out.print(a / b + " " + a % b + "/" + b);//原代码是(a % b) % b,对b取余一定小于b,多做一次取余操作还是原数,删去
		} /*//这一步与第一个重了,可以省去
		  else if (a == b) {
			System.out.print(1);
		}*/ else {
			System.out.print(a + "/" + b);
		}
 
		if (isMinus) {//若打印了左括号,输出右括号
			System.out.print(")");
		}
	}
 
	//除法
	public static void divide(long a1, long b1, long a2, long b2) {
		tackle(a1, b1);//计算第一个数并输出
		System.out.print(" / ");
		tackle(a2, b2);//计算第二个数并输出
		System.out.print(" = ");
		if (a2 == 0) {
			System.out.print("Inf");
		} else if (a2 < 0) {
			//a/b 除 c/d = ad/bc
			tackle(-1 * a1 * b2, -1 * a2 * b1);
		} else {
			tackle(a1 * b2, a2 * b1);
		}
	}
	//乘法
	public static void mutilply(long a1, long b1, long a2, long b2) {
		tackle(a1, b1);
		System.out.print(" * ");
		tackle(a2, b2);
		System.out.print(" = ");
		//a/b 乘 c/d = ac/bd
		tackle(a1 * a2, b1 * b2);
		System.out.println();
	}
	//减法
	public static void minus(long a1, long b1, long a2, long b2) {
		tackle(a1, b1);
		System.out.print(" - ");
		tackle(a2, b2);
		System.out.print(" = ");
		//减法,a/b 减 c/d 通分做计算,分子为ad-bc,分母为bd
		tackle(a1 * b2 - a2 * b1, b1 * b2);
		System.out.println();
	}
 
	//加法
	public static void add(long a1, long b1, long a2, long b2) {
		tackle(a1, b1);
		System.out.print(" + ");
		tackle(a2, b2);
		System.out.print(" = ");
		//加法,a/b 加 c/d 通分做计算,分子为ad+bc,分母为bd
		tackle(a1 * b2 + a2 * b1, b1 * b2);
		System.out.println();
	}
 
	//迭代法(递推法):欧几里得算法:计算分子分母的最大公约数
	public static long getGcd(long a, long b) {
		while (a % b != 0) {
			long temp = a % b;
			a = b;
			b = temp;
		}
		return b;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值