PAT 乙级 1034 有理数四则运算 Java 解决

写在最前:欢迎批评,欢迎任意地方的指正,用你们的优秀的java代码砸死我吧!!

问题——————

本题要求编写程序,计算 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的情况就可以了。最后就是一个坑,题中是说给出的数据不超过int类型,但是他没有说相乘的结果不会超出int,所以直接使用long类型来写,如果用int会使得两个错误点错误。

package not.die.in.here;

import java.io.*;
//满分
//他只是说保证所有给出是int,但是可能乘法乘出来超过int的类型
//直接用long
public class _1034_RationalCal {
	
	//静态内部类
	static class Rational{
		long up,down;//分子分母
		boolean sign;//符号,true代表+,false代表-
		String format;//最后的格式化的字符串存储
		public Rational() {}//无参构造器
		public Rational(String a) {//构造器,为了方便直接使用从外界读入的String格式
			if(a.indexOf('-')==0) {//如果第一个字符是-的话就是负数
				sign=false;//负数
				String[] buf = a.split("/");
				up = -Long.parseLong(buf[0]);//分别保存分子和分母
				down = Long.parseLong(buf[1]);
				simple();//调用化简函数
			}else {
				sign=true;//正数
				String[] buf = a.split("/");
				up = Long.parseLong(buf[0]);//分别处理
				down = Long.parseLong(buf[1]);
				simple();//调用化简
			}
		}
		public void simple() {
			if(up==0) {//首先,如果分子是0,那么值肯定是0
				format = "0";
				return;
			}else {
				long num = GCD(up,down);//最大公约数
				up = up/num;
				down = down/num;//最简
				if(up<down) {//真分数
						format = up+"/"+down;//直接分数形式
						return;
				}else {//假分数
					if(down == 1) {
						format=up+"";//如果是最简形式并且分母为1,那么直接输出分子
						return;
					}else {
						long x = up/down;//假分数变带分数
						long tempUp = up-down*x;
						format = x+" "+tempUp+"/"+down;
						return;
					}
				}
			}
		}
		@Override
		public String toString() {//把化简的值经过符号处理输出,后面使用的时候可以直接输出对象
			if(format.equals("0"))
				return format;
			if(sign)
				return format;
			else
				return "(-"+format+")";
		}
	}
	//欧几里得算法 递推法(效率最高)
	/*private static long GCD(long a,long b){
		return (a==0?b:GCD(b%a,a));
	}*/
	public static Rational add(Rational a,Rational b) {//加法
		Rational c = new Rational();
		if(!a.sign^b.sign) {//同正同负
			//同号情况下,值累加,符号不变
			c.down = a.down*b.down;
			c.up = a.up*b.down+b.up*a.down;
			c.sign=a.sign;
			c.simple();
			return c;
		}else {
			//异号情况下,值做差,取绝对值较大的符号
			c.down = a.down*b.down;
			c.up = Math.abs(a.up*b.down-b.up*a.down);
			if(a.up/a.down>=b.up/b.down)
				c.sign = a.sign;
			if(b.up/b.down>=a.up/a.down)
				c.sign = b.sign;
			c.simple();
			return c;
		}
	}
	public static Rational minus(Rational a,Rational b) {
		Rational c = new Rational();//相减的情况可以充分利用写好的代码,吧后面的数的符号相反,调用加法
		c.up = b.up;
		c.down = b.down;
		c.sign = !b.sign;
		return add(a,c);
	}
	public static Rational mulity(Rational a,Rational b) {
		//乘法,分子分母分别相乘,同号取正,异号取负
		Rational c = new Rational();
		c.up = a.up*b.up;
		c.down = a.down*b.down;
		c.sign = !a.sign^b.sign;
		c.simple();
		return c;
	}
	public static String devide(Rational a,Rational b) {
		//触发单独把返回值变成String,因为有INF的可能性
		if(b.toString().equals("0")) {
			return "Inf";//分母0则返回inf
		}else {//如果分母不是0,那就把b的分子分母调换,调用乘法,最后输出对象的toString
			Rational c = new Rational();
			c.up = b.down;
			c.down = b.up;
			c.sign = b.sign;
			return mulity(a,c).toString();
		}
	}
	public static long GCD(long a,long b) {
		while(b > 0) {//欧几里得
			long num = a%b;
			a=b;
			b=num;
		}
		return a;
	}
	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		String buf[] = bf.readLine().split("\\s+");//任意个空格分割
		Rational a = new Rational(buf[0]);
		Rational b = new Rational(buf[1]);
		//格式化直接输出
		System.out.println(a+" + "+b+" = "+ add(a, b));
		System.out.println(a+" - "+b+" = "+minus(a, b));
		System.out.println(a+" * "+b+" = "+mulity(a, b));
		System.out.println(a+" / "+b+" = "+devide(a, b));
	}

}

提交截图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值