执行给定数字的唯一因式分解的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 的平方根。
数学证明:
- 让 x < sqrt(n) 和 y < sqrt(n) 乘以两个方程 x×y < n 因此当任何 x 和 y 小于 n 时。任何 x 和 y 的乘积总是小于 n。
- 让 x > sqrt(n) 和 y > sqrt(n) 乘以两个方程 x×y > n 因此当任何 x 和 y 小于 n 时。任何 x 和 y 的乘积总是小于 n。
- 让一个数字低于 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 的倍数,依此类推,直到数组的长度。
0 | 1 | 2 | 3 | 2 |
---|
- 标记所有数字的所有剩余倍数,直到 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)