【蓝桥杯-Java】唯一分解定理超算给定 N 的约数个数

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚妄狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值