首页 > 编程语言 >[编程题]有理数运算

[编程题]有理数运算

时间:2023-08-19 21:32:44浏览次数:48  
标签:编程 有理数 运算 denominator long b1 b2 return RationalNum

Rational Arithmetic (20)__牛客网 (nowcoder.com)

输入描述:

每个输入文件只包含一个测试用例,测试用例会给出一行数据,格式为“a1/b1 a2/b2”分子分母的范围都在长整型的范围内,如果数字为负,则符号只会出现在分子的前面。分母一定是非零数。

输出描述:

针对每个测试用例,都输出四行,分别是这两个有理数的和、差、积和商,格式为“数1 操作符 数2 = 结果”。注意,所有的有理数都将遵循一个简单形式“k a/b”,其中k是整数部分,a/b是最简分数形式,如果该数为负数,则必须用括号包起来。如果除法中的除数为0,则输出“Inf”。结果中所有的整数都在long int的范围内。

思路分析

要计算和、差、积和商

a1/b1 + a2/b2 = (a1*b2 + a2*b1) / (b1 * b2);

a1/b1 - a2/b2 = (a1*b2 - a2*b1) / (b1*b2);

a1/b1 * a2/b2 = (a1*a2) / (b1*b2);

(a1/b1) / (a2/b2) =(a1/b1) * (b2 / a2)  = (a1 * b2) / (a2 * b1);

还要保证a/b是最简分数形式

分子和分母都除最大公约数

使用 辗转相除法,求最大公约数

遵循一个简单形式“k a/b”

负数,则必须用括号包起来

除数为0,则输出“Inf”

代码实现

import java.util.*;
class RationalNum {
    //分子
    private long numerator;
    //分母
    private long denominator;
    //整数部分
    private long integer;
    //判断符号
    private boolean isNegative = false;
    //判断分母为零
    private boolean isZero = false;
    //参与运算的分子
    private long totalNumerator;
    //构造方法 对这些值初始化
    public RationalNum(long n, long d) {
        if(d == 0) {
            isZero = true;
            return;
        }
        if(n < 0) {
            isNegative = true;
        }
        //经过除法计算可能将分母变为负数
        if(d < 0) {
            isNegative = !isNegative;
        }
        //如果输入是假分数转换为真分数
        integer = n / d;
        numerator = n - integer * d;
        denominator = Math.abs(d);
        //化简 分子分母同时除以最大公约数
        if(numerator > 1 || numerator < -1) {
            long gcd = isGcd(Math.abs(numerator), denominator);
            if(gcd > 0) {
                numerator /= gcd;
                denominator /= gcd;
            }
        }
        //进行计算的分子,一定是简化后
        totalNumerator = integer * denominator + numerator;
    }
    //辗转相除法,求最大公约数
    private long isGcd(long a, long b) {
        if(b == 0) {
            return a;
        }
        return isGcd(b,a % b);
    }
    //根据字符串得到分子
    public static long parseNumerator(String s) {
        return Long.parseLong(s.substring(0, s.indexOf("/")));
    }
    //根据字符串得到分母
    public static long paresDenominator(String s) {
        return Long.parseLong(s.substring(s.indexOf('/')+1));
    }
    //加法操作
    public RationalNum add(RationalNum r) {
        long n = totalNumerator * r.denominator + denominator * r.totalNumerator;
        long d = denominator * r.denominator;
        return new RationalNum(n, d);
    }
    //减法操作
    public RationalNum sub(RationalNum r) {
        long n = totalNumerator * r.denominator - denominator * r.totalNumerator;
        long d = denominator * r.denominator;
        return new RationalNum(n, d);
    }
    //乘法操作
    public RationalNum mul(RationalNum r) {
        long n = totalNumerator * r.totalNumerator;
        long d = denominator * r.denominator;
        return new RationalNum(n , d);
    }
    //除法操作
    public RationalNum div(RationalNum r) {
        long n = totalNumerator * r.denominator;
        long d = denominator * r.totalNumerator;
        return new RationalNum(n , d);
    }
    //对于输出进行重写
    @Override
    public String toString() {
        StringBuffer s = new StringBuffer();
        if(isZero) {
            s.append("Inf");
            return new String(s);
        }
        if(integer == 0 && numerator == 0) {
            s.append("0");
            return new String(s);
        }
        if(isNegative) {
            s.append("(-");
        }
        //有整数,注意与分子空格
        if(integer != 0) {
            s.append(Math.abs(integer));
            if(numerator != 0) {
                s.append(' ');
            }
        }
        //可能没有整数部分
        if(numerator != 0) {
            s.append(Math.abs(numerator));
            s.append('/');
            s.append(denominator);
        }
        if(isNegative) {
            s.append(')');
        }
        return new String(s);
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) { 
            //接收一个分数,next遇到换行空格等空白符停止,且不包含上述空白符
            String s = in.next();
            RationalNum r1 = new RationalNum(RationalNum.parseNumerator(s),RationalNum.paresDenominator(s));
           //在接收第二个分数
            s = in.next();
            RationalNum r2 = new RationalNum(RationalNum.parseNumerator(s),RationalNum.paresDenominator(s));
            System.out.println(r1 + " + " + r2 + " = " + r1.add(r2));
            System.out.println(r1 + " - " + r2 + " = " + r1.sub(r2));
            System.out.println(r1 + " * " + r2 + " = " + r1.mul(r2));
            System.out.println(r1 + " / " + r2 + " = " + r1.div(r2));
        }
    }
}

结果显示

[编程题]有理数运算_Math


标签:编程,有理数,运算,denominator,long,b1,b2,return,RationalNum
From: https://blog.51cto.com/u_16166203/7152316

相关文章

  • 面向对象编程
    面向对象编程多[多种]态[状态]基本介绍方法或对象具有多种状态,是面向对象的第三大特征多态的具体体现方法的多态对象的多态/*1.一个对象的编译类型和运行类型可以不一致2.编译类型在定义对象时,就确定了,不能改变3.运行类型是可以变化的4.编译类型看定义时=号的左......
  • java基础运算符04(扩展运算符,三元运算符,包机制)
    扩展赋值运算符扩展赋值运算符属于比较偷懒的一种方式,+=,-=,*=,/=都是同样的原理和运用方式,不深入学习,就代码示例一下publicclassDemo{publicstaticvoidmain(String[]args){inta=10;intb=20;a+=b;//a=a+bSystem.out.prin......
  • C语言编程的结构化要求和正确性与容错性要求
    一、结构化要求(1)禁止出现两条等价的支路。(2)禁止使用GOTO跳转语句。(3)用IF语句来强调只执行两组语句中的一组。禁止ELSEGOTO和ELSERETURN。(4)用CASE实现多路分支。(5)避免从循环引出多个出口。(6)3.6函数只有一个出口。(7)不使用条件赋值语句。(8)避免不必要的分支。(9)不要轻易用条件......
  • Linux网络编程(epoll函数的使用)
    (文章目录)前言本篇文章我们讲解epoll函数的使用方法,epoll相比于poll来说性能方面有所提升和改进。一、epoll概念特点讲解epoll是Linux上一种高性能的多路复用机制,用于监视大量文件描述符并在它们就绪时通知应用程序。它是在select和poll的基础上进一步优化和改进而来......
  • Java8编程 轻松驾驭数据流
    StreamAPI是 Java 8中最重要的新特性之一,它是处理集合和数组的一种新方式。它提供了一种简单、灵活和可读的方式来处理集合和数组中的元素,从而使代码更加简洁、高效和易于维护。1.原理介绍StreamAPI的核心是Stream接口,它表示一组元素的序列,可以按需进行计算。......
  • 程序代做服务:解放您的编程烦恼
    导言:在现代技术驱动的社会中,编程已经成为了解决问题和创新的重要手段。然而,不是每个人都拥有编程的技能和时间来完成复杂的编程任务。在这样的情况下,程序代做服务应运而生,为那些需要技术支持的个人和企业提供了便利。什么是程序代做服务?程序代做服务是一种服务模式,通过该模式,您......
  • 【LeetCode173. 最多连胜的次数】MySQL用户变量编程解法
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/longest-winning-streak/description/题目描述选手的 连胜数是指连续获胜的次数,且没有被平局或输球中断。编写解决方案来计算每个参赛选手最多的连胜数。结果可以以任何顺序返回。代码WITHt1AS(......
  • 【LeetCode1454. 活跃用户】MySQL 用户自定义变量,面向过程编程解决"连续天数"的问题
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/active-users/description/题目描述活跃用户是指那些至少连续 5天登录账户的用户。编写解决方案, 找到活跃用户的id和name。返回的结果表按照id排序 。代码注意需要处理,同一天多次登录的情形......
  • Google开源了可视化编程框架Visual Blocks for ML
    VisualBlocksforML是一个由Google开发的开源可视化编程框架。它使你能够在易于使用的无代码图形编辑器中创建ML管道。为了运行VisualBlocksforML。需要确保你的GPU是可以工作的。剩下的就是clone代码,然后运行,下面我们做一个简单的介绍:VisualBlocksforML是运行在支持jav......
  • Java基础运算符02(自增自减)
    自增自减++自增,--自减,为一元运算符,自增自减原理相同,仅以自增为例学习publicclassDemo{publicstaticvoidmain(String[]args){inta=5;System.out.println(a);System.out.println(a++);//只要调用了a++,不论是打印还是直接写,或者是赋......