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求水仙花数
下一篇:利用嵌套判断来完成成绩的等级判断