import java.math.BigInteger;
import java.util.ArrayList;
public class N的约数个数 {
public static void main(String[] args) {
System.out.println(founction1(384489L));
System.out.println(founction2(384489L));
System.out.println(founction3(384489L));
System.out.println(founctionSuper("384489"));
System.out.println(founction4(384489L));
}
public static int founction1(long n) { // 常规,性能差
int count = 0;
for (long i = 1; i <= n; i++) {
if (n % i == 0) {
count++;
}
}
return count;
}
/*
* 假如给定一个数 n = 36 , <算出它的倍数> 关系如下
* a == 1, 2, 3,4,6
* b == 36,18,12,9,6
* 36 = 1,2,3,4,6,9,12,18,36
* 最后一次的倍数 a = 6, b = 6 时, 36 = a * b,6 仅算一个约数,而不是两个
*/
public static int founction2(long n) { // 升级版
int count = 0;
for (long i = 1; i <= n / i; i++) { // 开根号的方式
if (n % i == 0) {
if (i != n / i) { // 补丁,最后一次仅 +1
count += 2;
} else {
count++;
}
}
}
return count;
}
/*
* 原理:给定一个 n ,假如 n = 36,求约数个数
* 36 分解定理 == 36 % 2 = 0;,18 % 2 = 0;9 % 3 = 0;3 % 3 = 0;
* 36 分解定理 == 2 * 2 * 3 * 3
* 36 分解定理 == 2的2次方 * 3的2次方
* 36 最终解法 == (2+1) * (2+1) == 3 * 3 == 9 个约数
* 36 == 1,2,3,4,6,9,12,18,36
* (PS:也就是用得到质因子个数,每个不同的质因子个数再 + 1,然后相乘)
*/
public static long founction3(long n) { // 数学超算版
long count = 1; // 乘法初始值1
for (long i = 2; i <= n / i; i++) { // 同样的开根号求
long powCount = 0;
while (n % i == 0) {
powCount++; // 从 2 的质因子开始计数个数
n /= i;
}
count *= powCount + 1;
}
// 打补丁,素数不能被 for 循环除 1 或 本身,bak 值也就会 > 1,还会有值未被除整后退出
// n 必须大于 1,因为最后得到的因数除了后,余数为 0 时,那么商就可能会得 1, 这个不计入,这个因数只记录一个。
// 只有当这个数为素数时,2最小素数,只能被 1 和本身整除,所以这个素数就被当作一个 质因数 + 1 == 2
if (n > 1) count *= 2;
return count;
}
// 大数的运行效率比 founction3() 方法慢
public static long founctionSuper(String n) { //参数也可以转换为大数
long count = 1;
BigInteger bg = new BigInteger(n);
final BigInteger zero = new BigInteger("0"), one = new BigInteger("1");
for (BigInteger i = new BigInteger("2"); i.compareTo(bg.divide(i)) <= 0; i = i.add(one)) {
long ans = 0;
while (bg.mod(i).compareTo(zero) == 0) {
++ans;
bg = bg.divide(i);
}
count *= ans + 1;
}
if (bg.compareTo(one) == 1) count *= 2;
return count;
}
public static long founction4(long n) { // 数学超算版 , 数组记录一下每个质因数
ArrayList<Long> pow = new ArrayList<>();
pow.add(n);
long count = 1; // 乘法初始值1
for (long i = 2; i <= n / i; i++) { // 同样的开根号求
long powCount = 0;
while (n % i == 0) {
powCount++; // 从 2 的次方开始计数个数
n /= i;
pow.add(i);
}
count *= powCount + 1;
}
// 打补丁,素数不能被 for 循环除 1 或 本身,bak 值也就会 > 1,还会有值未被除整后退出
// n 必须大于 1,因为最后得到的因数除了后,余数为 0 时,那么商就可能会得 1, 这个不计入,这个因数只记录一个。
// 只有当这个数为素数时,2最小素数,只能被 1 和本身整除,所以这个素数就被当作一个 质因数次方 + 1 == 2
if (n > 1) {
count *= 2;
pow.add(n);
}
StringBuilder sb = new StringBuilder();
sb.append(pow.get(0)).append(" = ");
for (int i = 1; i < pow.size(); i++) {
sb.append(pow.get(i));
if (i < pow.size() - 1) sb.append(" * ");
}
System.out.println(sb);
return count;
}
}
输出:
24
24
24
24
384489 = 3 * 3 * 7 * 17 * 359
24