java基础练习:求最大公约数和最小公倍数

方法1:自己思考的笨方法,太长太乱了。
通过得到相同的质因数,提取出来就是他们的最大公约数了

import java.util.ArrayList;

/**
 * @author cherhio
 * @date Created in 2019-05-05 13:55
 *
 * 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
 */
public class solution1 {
    public static void main(String[] args) {
       /* MaxAndMin(60,12);*/
        int digui = new solution1().digui(30, 20);
    }


    private static void MaxAndMin(int x,int y){
        /*
            如果x,y都是质数,最小公倍数为积,最大公约数=两数之积/最小公倍数

            分解公因式:
            20=2*2*5
            12=2*2*3

            最大公约数是 2 * 2 = 4,最小公倍数是 20 * 12 / 4 = 60


            再来一个, x=30,y=20;
            30=2*3*5
            20=2*2*5

            相同的数字是2跟5,2 * 5 =10,最大公约数是10,最小公倍数是30 * 20 / 10  = 60;
            如何得到他们的相同的数字?

            遍历一个集合,判断另外一个集合是否包含该数字,包含的话,放入第三个集合。
            遍历第三个集合得出的乘积就是最小公倍数.

         */
        if (isPrime(x) && isPrime(y)){
            System.out.println("最大公约数是:"+1);
            System.out.println("最小公倍数是:"+(x * y));
            return;
        }



        ArrayList listX = decomposedPrimeNumber(x);
        ArrayList listY = decomposedPrimeNumber(y);
        ArrayList<Integer> sameNums = getSameNums(listX, listY);
        int result = 1;
        for (Integer sameNum : sameNums) {
            result *= sameNum;
        }

        System.out.println("最大公约数是:"+result);
        System.out.println("最小公倍数是:"+(x * y)/result);

    }


    private static ArrayList<Integer> getSameNums(ArrayList<Integer> x, ArrayList<Integer> y){

        ArrayList<Integer> same = new ArrayList<>();

        //遍历,得到相同的数字,存入sam数组。
        for (Integer integer : x) {
            if (y.contains(integer)){
                same.add(integer);
            }
        }

        return same;


    }

    /**
     * 分解质因数
     * @param n
     */

    private static ArrayList<Integer> decomposedPrimeNumber(int n){
        ArrayList<Integer> list = new ArrayList<>();


        /*
        程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
        (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
        (2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第一步。
        (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
         */

        //找到一个最小的质数k
        int k = 0;
        for (int i = 2; i < n; i++) {
            if (isPrime(i)){
                k = i;
                break;
            }
        }

        //保留原始数,方便打印的时候展示
        int i = n;


        //(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
        while (k != n){
            //(2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第一步。
            if (n != k && n % k == 0){
                list.add(k);
                n = n / k;
            }else {
                //(3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
                k = k + 1;
            }
        }
        list.add(k);
        return list;

    }



    /**
     * 判断质数的方法
     * @param n
     *
     */
    private static boolean isPrime(int n){
        for (int i = 2; i < n; i++) {
            if (n % i == 0){
                return false;
            }
        }
        return true;
    }
}

方法2:使用辗除法:

/**
 * @author cherhio
 * @date Created in 2019-05-05 15:56
 */
public class solution2 {
    public static void main(String[] args) {
        new solution2().getGcdAndLcm(12,24);
    }

    @SuppressWarnings("SameParameterValue")
    private void getGcdAndLcm(int x,int y){
        if (x <=0 || y <= 0){
            return;
        }
        int gcd = new solution2().recursion(x, y);
        int lcm = x * y / gcd;
        System.out.println("最大公约数是:"+gcd);
        System.out.println("最小公倍数是:"+lcm);
    }

    private int recursion(int x,int  y){
        if (y != 0){
            return recursion(y,x % y);
        }else {
            return x;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44355126/article/details/89847989