构造有理数~

在编程中,数据类型基本会有数字类型,有的还会细分整数和小数,但是一般不会区分有理数与无理数。辣么,如何打造一个有理数类型呢?

什么是有理数类型?首先有理数就是分数。其次,有理数既然是一种数据结构,就有创建和操作的方法。

——————— 启发与 sicp ——————-

其实实现语言不重要,这里表达的是一种抽象分层的思想。(假装有)

java 实现:

package com.pycat.simple.ration;

import javafx.util.Pair;

/**
 * Created by cat on 2018/6/10.
 * 有理数
 */
public class Ration<K, V> extends Pair<K, V> {


    /**
     * Creates a new pair
     *
     * @param key   The key for this pair
     * @param value The value to use for this pair
     */
    Ration(K key, V value) {
        super(key, value);
    }

    @Override
    public String toString() {
        if (getValue() instanceof Integer) {
            int v = (Integer) getValue();
            return v == 1
                    ? String.format("Ration(%s)", getKey())
                    : String.format("Ration(%s/%s)", getKey(), getValue());
        } else if (getKey() == getValue()) {
            return String.format("Ration(%s)", 1);
        }
        return String.format("Ration(%s/%s)", getKey(), getValue());
    }
}
package com.pycat.simple.ration;

import com.pycat.simple.ration.Ration;

/**
 * Created by cat on 2018/6/10.
 * 有理数操作
 */
public class RationOperator {

    private RationOperator() {
    }

    public static Ration<Integer, Integer> makeRation(int n, int d) {
        if (d == 0) throw new ArithmeticException("denomination can't be zero.");
        return new Ration<>(n / gcd(n, d), d / gcd(n, d));
    }

    public static int getNumber(Ration<Integer, Integer> ration) {
        return ration.getKey();
    }


    public static int getDenominate(Ration<Integer, Integer> ration) {
        return ration.getValue();
    }

    /**
     * 有理数相加
     *
     * @param x ration
     * @param y ration
     * @return x + y (其中 x,y 都是有理数)
     */
    public static Ration<Integer, Integer> add(Ration<Integer, Integer> x, Ration<Integer, Integer> y) {

        int n = x.getKey() * y.getValue() + x.getValue() * y.getKey();
        int d = x.getValue() * y.getValue();

        return makeRation(n, d);
    }

    /**
     * 有理数相减
     *
     * @param x ration
     * @param y ration
     * @return x - y (其中 x,y 都是有理数)
     */
    public static Ration<Integer, Integer> minus(Ration<Integer, Integer> x, Ration<Integer, Integer> y) {

        int n = x.getKey() * y.getValue() - x.getValue() * y.getKey();
        int d = x.getValue() * y.getValue();

        return makeRation(n, d);
    }

    /**
     * 有理数相乘
     *
     * @param x ration
     * @param y ration
     * @return x * y (其中 x,y 都是有理数)
     */
    public static Ration<Integer, Integer> multi(Ration<Integer, Integer> x, Ration<Integer, Integer> y) {
        int n = x.getKey() * y.getKey();
        int d = x.getValue() * y.getValue();
        return makeRation(n, d);
    }

    /**
     * 有理数相除
     *
     * @param x ration
     * @param y ration
     * @return x / y (其中 x,y 都是有理数)
     */
    public static Ration<Integer, Integer> divide(Ration<Integer, Integer> x, Ration<Integer, Integer> y) {

        return multi(x, makeRation(y.getValue(), y.getKey()));
    }


    /**
     *
     * 第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
     * 第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
     * 则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。
     * 其中所说的“等数”,就是最大公约数。求“等数”的办法是“更相减损”法。所以更相减损法也叫等值算法。
     *
     * @param n
     * @param d
     * @return
     */
    private static int gcd(int n, int d) {
        int before = 1;
        while (n % 2 == 0 && d % 2 == 0) {
            n = n / 2;
            d = d / 2;
            before *= 2;
        }
        int r = 0;
        int max;
        int min;
        max = Math.max(n, d);
        min = Math.min(n, d);
        n = max;
        d = min;
        while (r != d) {
            r = n - d;
            n = Math.max(r, d);
            d = Math.min(r, d);

            max = Math.max(n, d);
            min = Math.min(n, d);
            n = max;
            d = min;
        }
        return r * before;
    }

    public static void main(String[] args) {
//        System.out.println(gcd(6, 8));

        Ration<Integer, Integer> a = RationOperator.makeRation(1, 2);
        Ration<Integer, Integer> b = RationOperator.makeRation(1, 4);
        System.out.println(String.format("%s + %s = %s", a, b, RationOperator.add(a, b)));
        System.out.println(String.format("%s - %s = %s", a, b, RationOperator.minus(a, b)));
        System.out.println(String.format("%s * %s = %s", a, b, RationOperator.multi(a, b)));
        System.out.println(String.format("%s / %s = %s", a, b, RationOperator.divide(a, b)));
    }
}

猜你喜欢

转载自blog.csdn.net/ducklikejava/article/details/80642085
今日推荐