Java经典例题50题 ----4 、Java 合数分解质因数的两种方法

Java 合数分解质因数的两种方法

先看看题目:【程序 4】

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

解题的思路方法已经在题目中给出,下面关于怎样在程序中实现。我这里做了两种方法的。有兴趣的朋友可以路过的时候瞅瞅。方法都已经写在程序的注释中,本人自我源码注释已经足够详细,所以这里就不再多说了。如实在有不明白的,可联系我:qq:2530318393,或者留言,另外:写作不易,转载请声明所属~~~~~~~~

唯一提醒的是:方法二的质数的范围不能太大!否则将会花费你电脑大量的资源,而且还需要大量的时间。我当时整了个0x7fffffff,等了个5分钟左右都没整出来!所以就算是玩玩,范围也别太大!

/**
 * @program: 分解质因数
 * @description: 分解质因数实验程序入口
 * @author: Mr.XiaoShi
 * @create: 2020-08-31 14:43
 **/

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

import java.util.Arrays;
import java.util.Scanner;

/**
 * 上面是题目给的思路,我个人目前也没啥其余的解题思路,就说说一下自己在程序上的想法实现吧。
 * 1、我们都知道质数的常规方法就是通过对小于它的sqrt()的数进行取模判断,具体算下来就是有两个循环:
 *      一个n进行遍历因子除法的循环,以及能整除时对因子是否质数的判断的循环。这种情况下,那个数的因子较少
 *      ,需要分解的数的数量较少的情况下较为实用。但是需要判断的数的数量越多,数的因子较多的情况下,
 *      我觉得这种方法就不实用了。
 * 2、另外一种方法就是:根据需要判断的数的范围,确定因子的范围,将这个范围内的质数统统通过静态代码块事先加载出来,
 *      存在数组中,然后接下来就是只根据数组进行寻找它的因子,这种方法的缺点可能就是相对而言有点费内存,但是在
 *      执行起来效率会相对而言更高。
 *
 * **/

public class Program {
    static int[] Primes = new int[1];   //先定义一个静态数组,长度先给他1
    static final int scope = 1000;   //定义一个不可修改的定制变量,质因子的范围

    /*静态代码块,利用循环把固定的范围内的质数找出来存起来*/
    static {
        for (int i = 2; i < scope; i++) {
            if (Prime(i)){
                Primes[Primes.length - 1] = i;  //将这个质数存起来
                Primes = Arrays.copyOf(Primes,Primes.length+1);  //数组扩容
            }
        }
    }

    /**·······~~~~~¥¥¥¥¥¥¥程序的入口¥¥¥¥¥¥¥~~~~~~·······**/
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);   //new一个输入类对象
        int number = 0;
        while (true)
        {
            System.out.print("请输入一个 整数:");
            number = scanner.nextInt();
            System.out.print(number+" 通过方法一分解质因数后结果为:"+number+" = ");
            dedecomposition(number);
            System.out.print(number+" 通过方法二分解质因数后结果为:"+number+" = ");
            decomposition(number,Primes);   //分解质因数
        }
    }
    /**
    *@Description: 使用递归方法来完成分解质因数
    *@Param:
    *@return:  void
    *@Author: your name
    *@date: 2020/8/31 0031
    **/
    static void decomposition(int number,int[] primes){   //把质数数组与要分解的数传过来作为参数

        for (int i = 0; i < primes.length && number >= primes[i]; i++) {   //以数组作为循环遍历被分解数的因数
            if (number % primes[i] == 0)   //如果取模等于零
            {
                if (number == primes[i])   //这是代表分解结束的一种特殊的取模等于零的情况,即合数与因数相等
                {
                    System.out.println(primes[i]);   //相等就输出这个因数
                    return;// 然后提前结束此次递归
                }
                System.out.print(primes[i]+" * ");  //未分解结束时,输出因数
                number = number / primes[i];  //将商作为新的合数,即合数的更新
                break;  //结束此循环
            }
        }
        decomposition(number,primes);   //将商作为新的合数,进入下一次递归
    }
    /**
    *@Description: 重载分解质因数的方法,参数:需要分解的数
    *@Param:
    *@return: void
    *@Author: your name
    *@date: 2020/8/31 0031
    **/
    static void dedecomposition(int number){
        boolean over = true;   //分解完成循环条件
        while (over){
            for (int i = 2; i <= number; i++) {   //遍历查找因数
                if (number % i == 0)   //是否是因数
                {
                    if (Prime(i)) {    //是因数的前提下再判断是不是质数
                        if (number == i)  //在确定是质因数的前提下判断合数与因数是否相等,即是否分解完成
                        {
                            System.out.println(i);   //分解完成输出
                            over = false;   //改变最外部循环条件
                        }
                        else    //否则就输出,更新合数
                        {
                            System.out.print(i + " * ");
                            number /= i;
                        }
                        break;  //退出此循环
                    }
                }
            }
        }
    }
    /**
    *@Description: 传入一个整数,判断它是否是质数,是就返回true,否则就是false
    *@Param:
    *@return: boolean
    *@Author: your name
    *@date: 2020/8/31 0031
    **/
    static boolean Prime(int primeNum){   //传入需要判断的数
        for (int j = 2; j <= Math.sqrt(primeNum); j++) {   //循环取模
            if (primeNum % j == 0){
                return false;   //有除了1和本身的其余因子,代表不是质数,返回假
            }
        }
        return true;   //能成功结束循环代表是,返回真
    }

}

这是运行结果
在这里插入图片描述
上一篇:Java求水仙花数

下一篇:利用嵌套判断来完成成绩的等级判断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值