📜  执行给定数字的唯一因式分解的Java程序

📅  最后修改于: 2022-05-13 01:55:01.550000             🧑  作者: Mango

执行给定数字的唯一因式分解的Java程序

给定一个数n ,任务是编写一个高效的程序来打印 n 的所有唯一质因数。

例子

Input: 12
Output: 2, 3
Explanation: All prime factors or 12 are 2, 2, 3. In those factors, unique factors
         are 2 and 3.

Input: 315 
Output: 3, 5, 7

找到所有质因数的步骤

1)当 n 可被 2 整除时,打印 2 并将 n 除以 2。

2)在第 1 步之后,n 必须是奇数。现在开始从 i = 3 到 n 的平方根的循环。当 i 除以 n 时,打印 i 并将 n 除以 i,将 i 增加 2 并继续。

3)如果n是一个质数并且大于2,那么n不会通过以上两步变成1。因此,如果 n 大于 2,则打印 n。

在第二步中,循环运行到 n 的平方根,因为只有当一个数小于 n 的平方根且第二个数大于等于平方根时,才有可能生成第 n 个数的乘积的

例如,设 n =16 16 的平方根为 4 且 16 的因数为 1×16, 16×1, 2×8, 8×2, 4×4 在此序列中第一个数字应小于或等于n 的平方根,第二个数字大于等于 n 的平方根。

数学证明:

  1. 让 x < sqrt(n) 和 y < sqrt(n) 乘以两个方程 x×y < n 因此当任何 x 和 y 小于 n 时。任何 x 和 y 的乘积总是小于 n。
  2. 让 x > sqrt(n) 和 y > sqrt(n) 乘以两个方程 x×y > n 因此当任何 x 和 y 小于 n 时。任何 x 和 y 的乘积总是小于 n。
  3. 让一个数字低于 sqrt(n),第二个数字高于 sqrt(n)。在这种情况下,总是至少有一对乘积为 n 的数字。设 x 和 y 是乘积为 n 的两个数。我们可以写出 x = sqrt(n) * sqrt(n)/y ⇾ 方程 1st

有两个条件:

  • 当 y < sqrt(n) 即 1 < sqrt(n)/y 所以我们可以写出第一个方程 x = sqrt(n)*(1+b) 因此 x > sqrt(n)
  • 当 y < sqrt(n) 即 1 > sqrt(n)/y 所以我们可以写出第一个方程 x = sqrt(n)*(1-b) 因此 x < sqrt(n)。

因此,我们可以得出结论,对于 x*y=n,至少有一个数小于等于 sqrt(n) 或大于等于 sqrt(n)

这个概念被用在许多数论算法中,比如筛子、找到 n 的所有因数等

寻找给定数的唯一质因数的方法

1. 使用HashSet的方法

  • 当 n 可被 2 整除时,将 2 存储在集合中并将 n 除以 2。
  • 经过上述步骤后,n 必须是奇数。现在开始从 i = 3 到 n 的平方根的循环。当 i 除以 n 时,将 i 存储在集合中并将 n 除以 i。在 i 除以 n 失败后,将 i 增加 2 并继续。
  • 如果n是素数并且大于2,那么n不会通过以上两步变成1。因此,如果它大于 2,则存储在集合 n 中。
Java
// Java Program to print all unique prime factors
 
import java.io.*;
import java.lang.Math;
import java.util.*;
class GFG {
 
    // A function to print all prime factors
    // of a given number n
    public static void primeFactors(int n,
                                    HashSet h)
    {
        // Print the number of 2s that divide n
        while (n % 2 == 0) {
 
            h.add(2);
            n /= 2;
        }
 
        // n must be odd at this point. So we can
        // skip one element (Note i = i +2)
        for (int i = 3; i <= Math.sqrt(n); i += 2) {
 
            // While i divides n, print i and divide n
            while (n % i == 0) {
                h.add(i);
                n /= i;
            }
        }
 
        // This condition is to handle the case when
        // n is a prime number greater than 2
        if (n > 2)
            h.add(n);
    }
    static void printFactors(HashSet H)
    {
        // Itearator over the HashSet
        Iterator It = H.iterator();
 
        // printing the elements of HashSet
        while (It.hasNext()) {
 
            System.out.print(It.next() + " ");
        }
        System.out.println();
    }
    public static void main(String[] args)
    {
        int n = 15;
        HashSet h = new HashSet<>();
 
        primeFactors(n, h);
 
        // print the unique factors
        printFactors(h);
    }
}


Java
// Java Program to print all unique prime factors
 
import java.util.*;
import java.io.*;
 
public class GFG {
    static int dp[] = new int[100001];
 
    static void fill()
    {
        int n = 100000;
        for (int i = 1; i <= n; ++i) {
            dp[i] = i;
        }
       
        // mark the multiply of 2
        for (int i = 2; i <= n; i += 2) {
            dp[i] = 2;
        }
       
        // mark the multilple of less than sqrt(n)
        for (int i = 3; i <= Math.sqrt(n); ++i) {
            for (int j = i * i; j <= n; j += i) {
                if (dp[j] == j) {
                    dp[j] = i;
                }
            }
        }
    }
    static void Factors(int n, HashSet h)
    {
 
        // when n is prime number
        if (dp[n] == n) {
            h.add(n);
            return;
        }
        else {
            while (dp[n] != n) {
 
                // Adding the multiple.
                h.add(dp[n]);
                n = n / dp[n];
            }
            h.add(n);
            return;
        }
    }
    static void print(HashSet h)
    {
        Iterator it = h.iterator();
 
        // printing the elements
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
    }
 
    public static void main(String[] args)
    {
        int n = 21;
        fill();
        HashSet h = new HashSet<>();
 
        // finding the factors
        Factors(n, h);
        print(h);
    }
}


输出
3 5

时间复杂度: O(sqrt(n))

2. 使用筛子的方法:

  • 标记所有数字的倍数,直到上面提到的 sqrt(n) 原因,其中 n 是数组的最大长度。
  • 该数组看起来像 2 的倍数,依此类推,直到数组的长度。
01232
  • 标记所有数字的所有剩余倍数,直到 sqrt(n)。用于找到第 n 个数字的因数。
    • 将 n 与 n/dp[n] 相除,直到 dp[n]!=n
    • 将所有 dp[n] 值存储在 HashSet 或 TreeSet 中,最后将 n 存储在集合中。
    • 打印唯一因子的集合。

Java

// Java Program to print all unique prime factors
 
import java.util.*;
import java.io.*;
 
public class GFG {
    static int dp[] = new int[100001];
 
    static void fill()
    {
        int n = 100000;
        for (int i = 1; i <= n; ++i) {
            dp[i] = i;
        }
       
        // mark the multiply of 2
        for (int i = 2; i <= n; i += 2) {
            dp[i] = 2;
        }
       
        // mark the multilple of less than sqrt(n)
        for (int i = 3; i <= Math.sqrt(n); ++i) {
            for (int j = i * i; j <= n; j += i) {
                if (dp[j] == j) {
                    dp[j] = i;
                }
            }
        }
    }
    static void Factors(int n, HashSet h)
    {
 
        // when n is prime number
        if (dp[n] == n) {
            h.add(n);
            return;
        }
        else {
            while (dp[n] != n) {
 
                // Adding the multiple.
                h.add(dp[n]);
                n = n / dp[n];
            }
            h.add(n);
            return;
        }
    }
    static void print(HashSet h)
    {
        Iterator it = h.iterator();
 
        // printing the elements
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
    }
 
    public static void main(String[] args)
    {
        int n = 21;
        fill();
        HashSet h = new HashSet<>();
 
        // finding the factors
        Factors(n, h);
        print(h);
    }
}
输出
3 7

时间复杂度: O(logn)