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

题目

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;
}

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

小结

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值