【JAVA】PAT 乙级 1034 有理数四则运算

本文详细解析了PAT乙级1034有理数四则运算题目,通过自定义分数类实现加、减、乘、除运算,并将结果转换为最简形式。文章提供了完整的Java代码示例,包括输入处理、运算逻辑及输出格式化。

【JAVA】PAT 乙级 1034 有理数四则运算


题目链接
本题要求编写程序,计算 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

模拟题,模拟分数加减乘除的过程,整体不难,但是要比较细心,要注意约分,转换成带分数,分子为0等各种情况
虽然题目说给出的数字都在整型范围内,但是运算的时候回超过整型的范围,所以要用long
博主用一个类f,来储存分数的分子分母,在类里写分数的四则运算



import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String fa = sc.next();
		String fb = sc.next();
		f a = getf(fa);
		f b = getf(fb);
		System.out.println(opf(a) + " + " + opf(b) + " = " + opf(a.add(b)));
		System.out.println(opf(a) + " - " + opf(b) + " = " + opf(a.min(b)));
		System.out.println(opf(a) + " * " + opf(b) + " = " + opf(a.mul(b)));
		f d = a.div(b);
		System.out.println(opf(a) + " / " + opf(b) + " = " + (d == null ? "Inf" : opf(d)));

	}

	static String opf(f a) {
	//输出分数a的方法
		long fz = a.fz, fm = a.fm;//获取a的分子和分母
		long z = fz / fm;//获取证书部分
		long m = Math.abs(fz) % fm;//转换成带分数后的分子
		String r = "";//输出结果
		if (m == 0) {
		//转换成带分数后分子为0,即分子是分母的倍数
		//直接输出证书部分
			r = z + "";
		} else {
		//转换成带分数后分子不为0
			if (z == 0) {
			//整数部分为0
			//判断分子是否小于0,小于0要在前面加负号
				r = (fz < 0 ? -m : m) + "/" + fm;
			} else {
			//整数部分不为0,转换成带分数后分子也不为0
				r = z + " " + m + "/" + fm;
			}
		}

		if (z < 0 || (z == 0 && fz < 0)) {
		//如果该分数是负数,则要在该分数两旁加括号
			r = "(" + r + ")";
		}
		return r;
	}

	static f getf(String t) {
		String[] ab = t.split("/");
		long a = Long.parseLong(ab[0]);
		long b = Long.parseLong(ab[1]);
		return new f(a, b);

	}

	static class f {
		long fz;
		long fm;

		f() {

		}

		f(long ia, long ib) {
		//初始化的时候直接约分
			long g = gcd(Math.abs(ia), ib);
			fz = ia / g;
			fm = ib / g;

		}

		f add(f b) {
		//分数加法
			long fm = this.fm * b.fm;
			long fz = this.fz * b.fm + b.fz * this.fm;
			return new f(fz, fm);
		}

		f min(f b) {
		//分数减法
			long fm = this.fm * b.fm;
			long fz = this.fz * b.fm - b.fz * this.fm;
			return new f(fz, fm);
		}

		f mul(f b) {
		//分数乘法
			long fz = this.fz * b.fz;
			long fm = this.fm * b.fm;
			return new f(fz, fm);
		}

		f div(f b) {
		//分数除法
			if (b.fz == 0) {
			//除以0的情况,返回null
				return null;
			}
			//乘以b的倒数
			long fz = this.fz * b.fm;
			long fm = this.fm * b.fz;
			//相乘后可能分子和分母可能都有可能出现负数,所以要进行判断
			if ((fz < 0 && fm > 0) || (fm < 0 && fz > 0)) {
			//分子和分母只有一个是负数
				fz = -Math.abs(fz);
				fm = Math.abs(fm);
			} else {
			//分子分母都是负数或都是正数
				fz = Math.abs(fz);
				fm = Math.abs(fm);
			}
			return new f(fz, fm);
		}
	}

	static long gcd(long a, long b) {
	//求最大公约数
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}
}

### Java 实现 PAT 乙级 1028 人口普查 对于PAT乙级1028人口普查问题,在Java中的实现可以遵循以下逻辑结构。此题旨在处理一系列人的出生日期,找出最早最晚出生的人,并统计总人数。如果没有任何记录,则需输出特定的信息。 #### 数据读取与预处理 程序首先需要接收输入的数据量N,之后逐行读入每个人的姓名及其对应的出生日期。为了方便后续操作,建议将这些信息封装到一个类中以便管理[^3]。 ```java import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; class Person { String name; Date birthday; public Person(String name, String dateStr) throws ParseException { this.name = name; SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); this.birthday = sdf.parse(dateStr); } } ``` #### 主要功能实现 接下来定义主函数来完成核心业务逻辑:初始化变量用于保存最早的出生日期个人信息、最新的出生日期个人信息;遍历所有人对象列表更新上述两个极端值;最后按照题目要求格式化输出结果。 ```java public class Main { public static void main(String[] args) throws ParseException { Scanner scanner = new Scanner(System.in); int n = Integer.parseInt(scanner.nextLine()); List<Person> people = new ArrayList<>(); for (int i = 0; i < n; ++i){ String line = scanner.nextLine(); String[] parts = line.split(" "); people.add(new Person(parts[0], parts[1])); } if(n == 0){ System.out.println(0); return ; } Collections.sort(people, Comparator.comparing(p -> p.birthday)); Person oldestPerson = people.get(0); Person youngestPerson = people.get(people.size() - 1); System.out.printf("%d %s %s\n",n ,youngestPerson.name,oldestPerson.name ); } } ``` 这段代码实现了对给定数据的有效处理,能够正确识别并打印出最年轻的个体名、最年老的个体名以及参与调查者的总数。当没有有效条目时,仅显示数字零作为指示[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值