1059 Prime Factors 一文读懂素数的应用

本文详细介绍了质因数分解的基本概念,提供了两种不同的算法实现,包括利用素数判断函数和筛选法构建素数表,以及如何应用这些素数表进行高效质因数分解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format在这里插入图片描述

分析

题意是给出一个long int 型的整数,让我们按规定格式输出其质因子。
质因子其实就是素数,所以这是一道关于素数的应用。

素数的判断

我们先来回顾一下关于素数的判断,数学定义是“除了1和他本身能整除外,没有其他数能整除的整数”,因此代码可以用只要有除1和他本身能整除的数就排除的方法来写代码:

bool isPrime(int n)
{
	if(n <= 1) return false;
	int sqr = (intsqrt(1.0 * n);
	for(int i = 2; i <= sqr; i++)
	{
		if(n % i == 0) return false;
	}
	return true;

素数表的获取

有了素数的判断,规定号表长后,我们可以很轻易地获取一个素数表,如下,设prime[i] = 1为素数,prime[i] = 0则不是素数:

const int maxn = 101;
int prime[maxn] = {0}, pNum = 0;
void Find_Prime()
{
	for(int i = 1; i < maxn; i++)
	{
		if(isPrime(i)) prime[i] = 1;
	}
}
void Find_prime()
{
	for(int i = 1; i < maxn; i++)
	{
		if(isPrime(i)) prime[Pnum++] = i;
	}
}

上面是两种获取素数表的写法,第一种是利用哈希的思想,若表的坐标为素数则为1,反之为0;第二种是把素数按从小到大放入一个表里;两种方法均能快速取得素数。

进阶-更快的素数表(筛选)

上面获取素数表的方法是利用素数判断函数,然后逐个判断和写入,时间复杂度为O(n*n^(1/2)),接下来介绍一种更快的建立素数表方法——筛选法:算法从小到大枚举所有数,对每个数筛去他的倍数,那么剩下的就是素数啦!如2,则筛去4,6,8,10…等等,如此类推:

const int maxn = 101;
int prime[maxn] , pNum = 0;
bool p[maxn] = {0};
void Find_Prime()
{
	for(int i = 2; i < maxn; i++)
	{
		if(p[i] == false)
		{
			prime[pNum++] = i;
			for(int j = i + i; j < maxn; j += i)
			{
				p[j] = true;
			}
		}
	}
}

以上算法没有用到素数判断函数,直接再筛是时候就把素数判断出来了,所以相比上一种方法省去了判断的操作,时间复杂度为O(n log log n)。

题目解答

//方法一:
//#include<cstdio>
//#include<cmath>
//
//const int maxv = 100010;
//
//bool is_prime(int n)
//{
//	if(n == 1) return false;
//	int sqr = (int) sqrt(n * 1.0);
//	for(int i = 2; i <= sqr; i++)
//	{
//		if(n % i == 0) return false;
//	}
//	return true;
//}
//
//int Prime[maxv], num = 0;
//
//void Find_prime()
//{
//	for(int i = 1; i < maxv; i++)
//	{
//		if(is_prime(i)) Prime[num++] = i;
//	}
//}
//
//struct factor
//{
//	int x, cnt;
//}fac[10];
//
//int main()
//{
//	Find_prime();
//	long int n; scanf("%ld", &n);
//	int fac_num = 0;
//	if(n == 1) printf("1=1");
//	else
//	{
//		printf("%ld=", n);
//		for(int i = 0; i < maxv; i++)
//		{
//			if(n % Prime[i] == 0)
//			{
//				fac[fac_num].x = Prime[i];
//				fac[fac_num].cnt = 0;
//				while(n % Prime[i] == 0)
//				{
//					fac[fac_num].cnt++;
//					n /= Prime[i];
//				}
//				fac_num++;
//			}
//			if(n == 1) break;
//		}
//		if(n > 1) 
//		{
//			fac[fac_num].x = n;
//			fac[fac_num].cnt = 1;
//		}
//		for(int i = 0; i < fac_num; i++)
//		{
//			if(i > 0) printf("*");
//			printf("%d", fac[i].x);
//			if(fac[i].cnt > 1) printf("^%d", fac[i].cnt);
//		}
//	}
//	return 0;
//}
方法二:
#include<cstdio>
#include<vector>
using namespace std;
vector<int> Prime(50000, 1);
int main()
{
	for(int i = 2; i*i < 50000; i++)
	{
		for(int j = 2; j*i < 50000; j++)
		{
			Prime[i*j] = 0;
		}
	}
	long int n; scanf("%ld", &n);
	printf("%ld=", n);
	if(n == 1) printf("1");
	int status = 0;
	for(int i = 2; i < 50000 && n > 1; i++)
	{
		int cnt = 0, flag = 0;
		if(Prime[i] == 1 && n % i == 0)
		{
			if(status) printf("*");
			while(n % i == 0)
			{
				cnt++;
				n /= i;
				flag = 1;
			}
		}
		if(flag)
		{
			printf("%d", i);
			if(cnt > 1) printf("^%d", cnt);
			status = 1;
		}
	}
	if(n > 1) printf("*%ld", n);
	return 0;
}

以上便是用两种不同方法解答的代码,实测第一种方法耗时是第二种方法耗时的三倍以上,还等什么,赶紧试试吧!

小结

素数的应用归根结底就是构建素数表,利用素数表进行输出,而素数表的构建有两个方法,一是利用素数的判断函数,判断并写入表内;二是利用筛选法,剩下的即为素数算法进行写入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值