java實現有理數分數相關計算(淺度拷貝)案例

啊道~ 發表於 2020-12-04

問題描述:java如何算1/2+1/3+1/6+1/5=???
在這裡插入圖片描述

程式碼實現

public class C6001_Rational implements Cloneable {
  private int numerator;//分子
  private int denominator;//分母
  public static int count;
  static {
      count = 0;//演示靜態初始化塊,這裡可以採用宣告初始化
  }

    public C6001_Rational() {
    }

    public C6001_Rational(int numerator, int denominator) {
        setNumerator(numerator);
        setDenominator(denominator);//使用set訪問器初始化,避免程式碼重複
    }


    public C6001_Rational(int x){
      this(x,1);//構造方法複用方式
    }
    public String getInfo(){
      simplify();
      if(denominator == 1)
      return String.valueOf(numerator);
      return  String.format("%d/%d",numerator,denominator);
    }

    public static int gcd(int a,int b)//求最小公倍數
    {
        int r;
        while ((r=a%b)!=0)
        {
            a=b;
            b=r;
        }
        return b;
    }

    public C6001_Rational add(C6001_Rational right)//方法資料型別為本類遞迴
    {
        //新分數分子=分子分母相+分子分母相乘  分母=分木*分母
        int x = this.numerator*right.denominator+this.denominator*right.numerator;
        int y = this.denominator*right.denominator;
        return new C6001_Rational(x,y);//呼叫構造方法初始化值
    }

    public C6001_Rational add(C6001_Rational y,C6001_Rational...args)
    {//使用可變引數實現多個引數加法,不要一個個構造方法那麼麻煩
        C6001_Rational sum = this.add(y);
        for (int i = 0; i < args.length; i++) {
            sum=sum.add(args[i]);
        }
        return sum;
    }

    public C6001_Rational sub(C6001_Rational right)//減法變為加法,加負數即可複用加法程式碼
    {
        C6001_Rational y = new C6001_Rational(-right.numerator,right.denominator);
        return  this.add(y);
    }
    public C6001_Rational mul (C6001_Rational right)
    {
        int x = this.numerator * right.numerator;
        int y = this.denominator * right.denominator;
        return new C6001_Rational(x,y);//借用構造方法來傳出兩個引數
    }
    //除法可變乘法,乘其倒數即可複用乘法程式碼
    public C6001_Rational div(C6001_Rational right)
    {
        C6001_Rational c = new C6001_Rational(right.denominator,right.numerator);
        return this.mul(c);
    }

    private void simplify()
    {
        int gcd = gcd(Math.abs(numerator),Math.abs(denominator));
        numerator = numerator/gcd;
        denominator = denominator/gcd;
        if(denominator<0)
        {
            numerator*=-1;
            denominator*=-1;
        }
    }
    // 重寫equals 方法
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
      C6001_Rational other = (C6001_Rational) obj;
      C6001_Rational result = other.sub(this);
      return result.numerator==0;
    }
    //重寫toString方法
    @Override
    public String toString() {
       simplify();
       if(denominator==1)//如果分母為1直接輸出分子
           return String.valueOf(numerator);
       return String.format("%d/%d",numerator,denominator);
    }

    //拷貝的方法
    @Override
    protected C6001_Rational clone() throws CloneNotSupportedException {
        return (C6001_Rational) super.clone();
    }


    public int getNumerator() {
        return numerator;
    }

    public void setNumerator(int numerator) {
        this.numerator = numerator;
    }

    public int getDenominator() {
        return denominator;
    }

    public void setDenominator(int denominator) {
      if(denominator!=0)
        this.denominator = denominator;
    }
}

主函式

public class Test implements Cloneable {
    public static void main(String[] args) throws CloneNotSupportedException {
        var x = new C6001_Rational(1,2);
        var y = new C6001_Rational(1,3);
        var z = new C6001_Rational(1,6);
        //toStrinf方法
        System.out.println("執行toString方法的結果"+x.toString());
        //進行比較方法equals方法
        boolean D = x.equals(y);
        System.out.println("執行equals方法的結果"+D);
        //執行拷貝方法clone
        C6001_Rational h = x.clone();
        h.setNumerator(1);
        h.setDenominator(5);
        C6001_Rational result = x.add(y).add(z).add(h);
        System.out.println("1/2+1/3+1/6+1/5 = "+result.getInfo());


    }
}