【编程题 】Rational Arithmetic(详细注释 易懂)

题目描述

题目链接:Rational Arithmetic (20)__牛客网
For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference,
product and quotient.

译文:对于两个有理数,你的任务是实现基本的算术运算,即计算它们的和、差,乘和商。

输入描述:

Each input file contains one test case, which gives in one line the two rational numbers in the format "a1/b1 a2/b2". 
The numerators and the denominators are all in the range of long int. If there is a negative sign, it must appear only in 
front of the numerator. The denominators are guaranteed to be non-zero numbers.

译文:每个输入文件包含一个测试用例,它在一行中给出了两个有理数,格式为“a1/b1 a2/b2”。
分子和分母都在 long int 的范围内。如果有负号,它必须只出现在在分子前面。分母保证是非零的数。


 

输出描述:

For each test case, print in 4 lines the sum, difference, product and quotient of the two rational numbers, respectively. The format of each 
line is "number1 operator number2 = result". Notice that all the rational numbers must be in their simplest form "k a/b", where k is 
the integer part, and a/b is the simplest fraction part. If the number is negative, it must be included in a pair of parentheses. If the 
denominator in the division is zero, output "Inf" as the result. It is guaranteed that all the output integers are in the range of long int.

译文:对于每个测试用例,在4行中分别打印两个有理数的和、差、积和商。各文件的格式
行是“number1 运算符 number2 = result”。注意,所有有理数必须是最简形式“k a/b”,其中k是整数部分,a/b是最简单的分式部分。如果数字是负数,它必须包含在一对圆括号中。如果
分母在除法中为零,输出“Inf”为结果。它保证所有输出整数都在长整型范围内。

示例1

输入

5/3 0/6

输出

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 特殊输出等系列问题。 牵扯的细节非常多,有一点没考虑到,这道题想做对,是非常难的。 

     不夸张的说,这道题,大多数人做出来,都是一百多行代码,我第一次做的时候,写了三百多行代码,几个小时,结果就过了 三个测试用例 。一气之下,我选择 删掉全部代码,重新思考如何 做这道题,有了下面的 比较简洁的代码。

解题思想:

     这道题,要想简单做,那就得有两个思想,一个是 模块化思想,另一个是 整数也是分数思想。有了这两个思想,你就能用最简洁的代码解出这道题。 首先,有一个 处理结果的 函数,它负责 区分整数和 分数,整数直接返回,分数化简,如果是负数,还要加括号再返回 。然后分别是 四个函数 加减乘除,这四个函数就按照我们正常的计算方法,计算就好了,整数一律视为 分母是1 的分数,这样区分的情况就会少很多 ,四个函数都是计算完 调用  处理结果的函数。 要提醒的,就两点,一个是 计算除法的时候,分母为 0 要单独处理 ,那分母输入不会为 0 ,什么时候会为0呢,答案是,它本身是整数0 ,还做被除数的时候 ; 还有一点是 计算出的负数,负号是跟着 分子的,但是作为被除数 它就跟着分母了 ,分母为负也是不行的,所以也要处理 。

   可能有人对除法的各个位置名称混淆,写一下 除数 / 被除数 = 商 

     还有一个易错的地方提醒,求最大公约数时一定要返回正数,否则你就会发现结果中,出现意料之外的负号。  在考试情况下,点击自测运行,它会显示 你的输出和它的结果相同,因为它是用 <br/>来表示换行的,但你点击 提交运行,就能直接跑过,这算是牛客的一个bug吧。

代码注释:

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        String str1 = scan.next();
        String str2 =scan.next();
      // 因为输入为 字符串,所以要 先从字符串里提取出 分子 和 分母
        long numerator1 = Integer.parseInt(str1.substring(0,str1.indexOf('/')));
        long denominator1 =Integer.parseInt(str1.substring(str1.indexOf('/')+1));
        long numerator2 = Integer.parseInt(str2.substring(0,str2.indexOf('/')));
        long denominator2 =Integer.parseInt(str2.substring(str2.indexOf('/')+1));
      // 把第一个数 处理为合规的数,然后直接输出
        String num1 = resultSort(numerator1,denominator1);
      // 把第二个数 处理为合规的数,然后直接输出
        String num2 = resultSort(numerator2,denominator2);
        String sumResult = sum(numerator1,denominator1,numerator2,denominator2);
        String differenceResult = 
               difference(numerator1,denominator1,numerator2,denominator2);
        String productResult = product(numerator1,denominator1,numerator2,denominator2);
        String quotientResult =quotient(numerator1,denominator1,numerator2,denominator2);
        System.out.println(num1+" "+ "+"+" "+ num2+" "+"=" +" "+sumResult);
        System.out.println(num1+" "+ "-"+" "+ num2+" "+"=" +" "+differenceResult);
        System.out.println(num1+" "+ "*"+" "+ num2+" "+"=" +" "+productResult);
        System.out.println(num1+" "+ "/"+" "+ num2+" "+"=" +" "+quotientResult);
        
        
    }
    // 这个就是处理 结果的函数
    public static String resultSort(long numerator1,long denominator1){
        String result ="";
        result += "(";
      // 这里 处理整数
       if(numerator1 % denominator1 == 0){
           result += numerator1 / denominator1;
         // 这里处理分数
       }else{
           // 算最大公约数
           long divisor = divisor(numerator1,denominator1);
           numerator1 /= divisor;
           denominator1 /= divisor;
              // 处理假分数
           if(numerator1 / denominator1 != 0){
               result += (numerator1 / denominator1)+" "+(Math.abs((numerator1 % 
                     denominator1)));
           }else{
                result += numerator1 ;
           }
           result += "/"+denominator1;
           
       }
         result += ")";
       // 针对结果是负数还是正数,进行分别处理
        if(result.charAt(1)!='-'){
            result = result.substring(1,result.length()-1);
        }
        return result;
    }
     // 求和函数
    public static String sum(long numerator1,long denominator1,long numerator2,long denominator2){
        numerator1 = numerator1 * denominator2 + denominator1*numerator2;
        denominator1 = denominator2* denominator1;
       return resultSort(numerator1,denominator1);
    }
   // 求差函数
    public static String difference(long numerator1,long denominator1,long numerator2,long denominator2){
        numerator1 = numerator1 * denominator2 - denominator1 * numerator2;
          denominator1 = denominator2* denominator1;
         return resultSort(numerator1,denominator1);
    }
        // 求 积函数
    public static String product(long numerator1,long denominator1,long numerator2,long denominator2){
        numerator1 = numerator1 * numerator2;
        denominator1 = denominator1 * denominator2;
        return resultSort(numerator1,denominator1);
    }
      // 求商函数
    public static String quotient(long numerator1,long denominator1,long numerator2,long denominator2){
        if(numerator2 == 0)
            return "Inf";
        numerator1 = numerator1 * denominator2;
        denominator1 = denominator1 * numerator2;
       // 如果商的分母是负数,那就给分子、分母同时取相反数
        if(denominator1 < 0){
            denominator1 = -denominator1;
            numerator1 = -numerator1;
        }
        return resultSort(numerator1,denominator1);
    }
    // 辗转相除法 求最大公约数
    public static long divisor(long numerator1,long denominator1){
        if(denominator1 == 0)
            return Math.abs(numerator1);
        return divisor(denominator1,numerator1 % denominator1);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值