数据结构与算法(1)——分解质因数及各种方法求最大公约数

1.分解质因数
2.质因数分解法、辗转相除法求两个数的最大公约数
3.质因数分解法、辗转相除法求n个数的最大公约数

完整的Java代码如下:

package algorithm;

import java.util.ArrayList;

public class GreatestCommonDivisor {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GreatestCommonDivisor gcd = new GreatestCommonDivisor();
        int i = 6;
        int j = 66;
        gcd.prime(i);// 分解质因数
        gcd.prime(j);// 分解质因数
        gcd.GCD_prime(i, j);// 质因数分解法
        gcd.GCD_successive1(i, j);// 辗转相除法,递归算法
        gcd.GCD_successive2(i, j);// 辗转相除法,循环算法

        int[] num = { 24, 36, 48, 66};
        gcd.gcd_n(num);// //递归调用求两个数的最大公约数的方法来求n个数的最大公约数
    }

    /*
     * 求n个数的最大公约数
     */
    public int gcd_n(int[] num) {
        int gcd = num[0];
        System.out.println("num[0]:" + gcd);
        for (int i = 1; i < num.length; i++) {
            System.out.println(gcd);
            gcd = GCD_successive1(gcd, num[i]);//递归计算
//          gcd = GCD_successive2(gcd, num[i]);//循环计算
            System.out.println("num[" + i + "]:" + num[i] + ";" + "gcd:" + gcd);
        }
        System.out.println("n个数的最大公约数为:" + gcd);
        return gcd;
    }

    /*
     * 辗转相除法,递归算法
     */
    int gcd1 = 0;
    public int GCD_successive1(int i, int j) {
        // a/b=q1...r1,b/r1=q2...r2当r=0时,b就是最大公约数
        int temp = i % j;
        if (temp == 0) {
            gcd1 = j;
            System.out.println("辗转相除法,递归计算最大公约数为j:" + j);
        } else {
            GCD_successive1(j, temp);// 递归调用,temp变化导致参数j变化,参数j变化导致参数i变化
        }
//      System.out.println("辗转相除法,递归计算最大公约数为j2:" + j);//此处第一次输出为正常值,后面的输出都为非正常值,这是由于栈先进后出导致,可以设置一个全局变量来解决
//      System.out.println("辗转相除法,递归计算最大公约数为gcd1:" + gcd1);
        return gcd1;
    }

    /*
     * 辗转相除法,循环算法
     */
    public int GCD_successive2(int i, int j) {
        // a/b=q1...r1,b/r1=q2...r2当r=0时,b就是最大公约数

        while (j != 0) {
            int remainder = i % j;
            i = j;
            j = remainder;
        }
        System.out.println("辗转相除法,循环计算最大公约数为:" + i);
        return i;
    }

    /*
     * 分解质因数
     */
    public String prime(int i) {
        StringBuffer str = new StringBuffer();
        // 短除法,一直用2...n的数去循环取所有数的余数
        int temp = i;
        for (int a = 2; a <= temp; a++) {
            while (temp % a == 0) {
                str.append(String.valueOf(a) + "*");
                temp /= a;
            }
        }
        System.out.println("分解质因数:" + i + "="
                + str.substring(0, str.length() - 1));
        return str.substring(0, str.length() - 1);
    }

    /*
     * 质因数分解法求最大公约数
     */
    public int GCD_prime(int i, int j) {
        int gcd = 1;// 最大公约数
        ArrayList list_i = new ArrayList();
        ArrayList list_j = new ArrayList();

        // 分解质因数
        for (int a = 2; a <= i; a++) {
            while (i % a == 0) {
                list_i.add(a);
                i /= a;
            }
        }

        for (int a = 2; a <= j; a++) {
            while (j % a == 0) {
                list_j.add(a);
                j /= a;
            }
        }

        // 判断公共质因数
        int k = 0;// 容器索引下标号
        if (list_i.size() <= list_j.size()) {
            while (k < list_i.size()) {
                // 判断是否是公共质因数,如果是则同时删除再循环判断
                if (list_j.contains(list_i.get(k))) {
                    gcd *= list_i.get(k);// 公有质因数的乘积即为最大公约数,最小公倍数为两个数的乘积除以最大公约数
                    list_j.remove(list_j.indexOf(list_i.get(k)));// 删除顺序不能变,不能先删除最基础项
                    list_i.remove(k);
                    k = 0;// 只要执行过删除操作,下次继续从容器的第一个值开始判断
                } else {
                    k += 1;
                }
            }
            System.out.println("质因数分解法,最大公约数为:" + gcd);
        } else {
            while (k < list_i.size()) {
                // 判断是否是公共质因数,如果是则同时删除再循环判断
                if (list_j.contains(list_i.get(k))) {
                    gcd *= list_i.get(k);
                    list_j.remove(list_j.indexOf(list_i.get(k)));// 删除顺序不能变,不能先删除最基础项
                    list_i.remove(k);
                    k = 0;// 只要执行过删除操作,下次继续从容器的第一个值开始判断
                } else {
                    k += 1;
                }
            }
            System.out.println("质因数分解法,最大公约数为:" + gcd);
        }
        return gcd;
    }
}

期待更好的方法及更高效代码

你可能感兴趣的:(数据结构与算法)