求两数最大公约数和最小公倍数


今天下午第一节算法课留的小作业,顺手做了吧。
最大公约数和最小公倍数的概念就不解释了,暴力法也不说了不可取。
这里说下 辗转相除法更相减损法

辗转相除法

辗转相除法,是求两个自然数的最大公约数的一种方法,也叫欧几里德算法。
假设m >= n,公式:gcd(m, n) = gcd(n, m mod n)
就是说m和n的最大公约数 = n和m/n的余数的,直到m mod n = 0,则n为最大公约数,而最小公倍数 = (mn)/gcd(m, n)
注:在代码中通常写做m / gcd(m,n) * n,防止m
n过大爆可能会爆数据范围
上Java代码

	public static int gcd(int m, int n) {
        return m % n == 0 ? n : gcd(n, m % n);
    }

    public static void main(String[] args) {

       //最大公约数     5
        System.out.println(gcd(25, 15));
        //最小公倍数     75
        System.out.println(25 / gcd(25, 15) * 15);
    }

更相减损法

公式:gcd(m, n) = gcd(n, m-n),直到m-n=0,则m或n就是最小公约数
输入两整数 m 和 n(m>=n):

1)若m-n=0,则m(或n)即为两数的最大公约数

2)若m-n≠0,则m=n,n=m-n 再回去执行第1步

	public static int gcd2(int m, int n) {
        return m - n == 0 ? n : gcd2(n, m - n);
    }

    public static void main(String[] args) {
    
        //最大公约数     5
        System.out.println(gcd2(25, 15));
        //最小公倍数     75
        System.out.println(25 / gcd2(25, 15) * 15);
    }

连续整数检测算法

总体策略就是先从最小的开始除,如果都除尽了就return,除不尽进-1,循环。

	public static int gcd3(int m, int n) {

        int gcd = 1;
        if (m == n) {
            return n;
        } else {
            int min = m > n ? n : m;
            for (int i = min; i > 1; i--) {
                if (n % i == 0 && m % i == 0) {
                    return i;
                }

            }
            return gcd;
        }
    }

	public static void main(String[] args) {
     
        //连续整数检测
        //最大公约数     5
        System.out.println(gcd3(25, 15));
        //最小公倍数     75
        System.out.println(25 / gcd3(25, 15) * 15);
    }

分解质因数然后找所有公因数求积

m、n分别分解质因数,然后两组进行对比找出所有的公因数,求积即为gcd


	 public static int gcd4(int m, int n) {
        if (m == n) {
            return n;
        } else {
            //m的因数
            List<Integer> _first = new ArrayList<>();
            //n的因数
            List<Integer> _second = new ArrayList<>();

            //m分解质因数
            for (int i = 2; i <= m; i++) {

                while (m % i == 0 && m != 0) {
                    m /= i;
                    _first.add(i);
                }
                if (m == i) {
                    _first.add(i);
                    break;
                }

            }

            //n分解质因数
            for (int i = 2; i <= n; i++) {

                while (n % i == 0 && n != 0) {
                    n /= i;
                    _second.add(i);
                }
                if (n == i) {
                    _second.add(i);
                    break;
                }

            }
            //克隆m的所有因数
            Set<Integer> tmp = new HashSet<>(_first);
            //在m因数中除去m因数与n因数中共有部分 即公因数
            tmp.removeAll(_second);
            //克隆m所有因数
            Set<Integer> exist = new HashSet<>(_first);
            //除去剩余的tmp,剩余exist即为所有公因数list
            exist.removeAll(tmp);

            int gcd = 1;
            for (Integer i :exist) {
                gcd*=i;
            }

            return gcd;
        }
    }

	public static void main(String[] args) {
        //公因数算法检测
        //最大公约数     5
        System.out.println(gcd4(25, 15));
        //最小公倍数     75
        System.out.println(25 / gcd4(25, 15) * 15);

    }

在这里插入图片描述

发布了41 篇原创文章 · 获赞 94 · 访问量 9568

猜你喜欢

转载自blog.csdn.net/qq_41718454/article/details/104255211