2022秋-Java-03-面向对象1(基础、封装)——6-1 分数【函数题】

2022秋-Java-03-面向对象1(基础、封装)——6-1 分数【函数题】

设计一个表示分数的类Fraction。这个类用两个int类型的变量分别表示分子和分母。注意,在创建和做完运算后应该化简分数为最简形式。如2/4应该被化简为1/2。

函数接口定义:

这个类的构造函数是:

Fraction(int a, int b)
  • 构造一个a/b的分数。

这个类要提供以下的功能:

double toDouble();
  • 将分数转换为double
Fraction plus(Fraction r);
  • 将自己的分数和r的分数相加,产生一个新的Fraction的对象。
Fraction multiply(Fraction r);
  • 将自己的分数和r的分数相乘,产生一个新的Fraction的对象。
String toString();
  • 将自己以“分子/分母”的形式产生一个字符串。如果分数是1/1,应该输出"1"。当分子大于分母时,不需要提出整数部分,即"31/30"是一个正确的输出。
裁判测试程序样例:
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Fraction a = new Fraction(in.nextInt(), in.nextInt());
        Fraction b = new Fraction(in.nextInt(), in.nextInt());
        System.out.println(a);
        System.out.println(b);
        System.out.println(a.plus(b));
        System.out.println(a.multiply(b).plus(new Fraction(5,6)));
        System.out.println(a);
        System.out.println(b);
        System.out.println(a.toDouble());
        in.close();
    }
}

/* 请在这里填写答案 */

注意,你的类的定义应该这样开始:

class Fraction {
  • 也就是说,在你的类的class前面不要有public。

输入样例:

2 4 1 3

输出样例:

1/2
1/3
5/6
1
1/2
1/3
0.5

解题代码如下:

class Fraction {
    /**
     * numer表示分数的分子 deno表示分数的分母
     */
    private int numer;
    private int deno;

    Fraction(int a, int b) {
        this.numer = a;
        this.deno = b;
    }

    /**
     * 转换成Double
     *
     * @return
     */
    double toDouble() {
        return this.numer*1.0/this.deno;
    }

    /**
     * 求两个分数相加
     *
     * @param r
     * @return
     */
    Fraction plus(Fraction r) {
        int newNumer = this.numer * r.getDeno() + r.getNumer() * this.deno;
        int newDeno = this.deno * r.getDeno();
        Fraction newFra = new Fraction(newNumer, newDeno);
        return newFra;
    }

    Fraction multiply(Fraction r) {
        Fraction newFra = new Fraction(this.numer * r.getNumer(), this.deno * r.getDeno());
        return newFra;
    }


//    @Override
//    public String toString() {
//        int gcd = getGcd(this.numer, this.deno);
//        this.numer /= gcd;
//        this.deno /= gcd;
//        if (this.deno==this.numer) {
//            return "1";
//        }else{
//            if(this.numer*this.deno<0){
//                return -1*Math.abs(this.numer) + "/" + Math.abs(this.deno);
//            }else{
//                return this.numer + "/" + this.deno;
//            }
//        }
//    }

    @Override
    public String toString() {
        int gcd = getGcd(Math.abs(this.numer), Math.abs(this.deno));
        this.numer /= gcd;
        this.deno /= gcd;
        if(this.numer<0 && this.deno<0){
            this.numer = -this.numer;
            this.deno = -this.deno;
        }
        if (this.numer == this.deno) {
            return "1";
        } else {
            return numer + "/" + deno;
        }
    }

    /**
     * 求两数最大公因数
     *
     * @param a
     * @param b
     * @return
     */
    int getGcd(int a, int b) {
        return b == 0 ? a:getGcd(b,a % b);
    }

    public int getNumer() {
        return numer;
    }

    public void setNumer(int numer) {
        this.numer = numer;
    }

    public int getDeno() {
        return deno;
    }

    public void setDeno(int deno) {
        this.deno = deno;
    }
}

解题要点:

  • 要学会求解gcd的算法。
  • 本题要考虑输出是负数的情况,也就是要对输出的符号进行判断和控制。
  • 本题对格式有特定的要求。尤其是toString处指出来的。

核心代码:

  • 用递归方式写gcd:
    /**
     * 求两数最大公因数
     *
     * @param a
     * @param b
     * @return
     */
    int getGcd(int a, int b) {
        return b == 0 ? a:getGcd(b,a % b);
    }
  • 分数化简和输出格式控制:
  • 方法一:
    @Override
    public String toString() {
        int gcd = getGcd(Math.abs(this.numer), Math.abs(this.deno));
        this.numer /= gcd;
        this.deno /= gcd;
        if(this.numer<0 && this.deno<0){
            this.numer = -this.numer;
            this.deno = -this.deno;
        }
        if (this.numer == this.deno) {
            return "1";
        } else {
            return numer + "/" + deno;
        }
    }
  • gcd不考虑符号,特殊情况下的符号特殊考虑

  • 方法二:

    @Override
    public String toString() {
        int gcd = getGcd(this.numer, this.deno);
        this.numer /= gcd;
        this.deno /= gcd;
        if (this.deno==this.numer) {
            return "1";
        }else{
            if(this.numer*this.deno<0){
                return -1*Math.abs(this.numer) + "/" + Math.abs(this.deno);
            }else{
                return this.numer + "/" + this.deno;
            }
        }
    }
  • 不去管gcd过程的符号
  • 但是管漏掉的符号控制的可能情况

详细来说就是要额外考虑 分子分母单负的情况和分子分母双负 的情况。

猜你喜欢

转载自blog.csdn.net/m0_54524462/article/details/126923522