版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/82077779
1.啥是素数啊?
小学知识点吧同志,百度词条官方定义:
质数(prime number)又称素数,有无限个。
质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
(与之相对的,自然就是合数啦)
2.素数的一些性质(持续更新)
1.质数的约数只有一和他本身。
2.唯一分解定理 : 一个大于1的整数一定可以被分解成若干质数的乘积
这个其实不必证明,任意一个数,如果本身是素数,那分解后就是他本身了;如果是合数,那他必然有除一和本身外别的约数,而这些约数或者是素数,或者又是合数,所以呢?往下分解不就成了,最终难道不是素数吗?你再想想吧,小帅逼。
以一个炒鸡简单的题为例:
假设x是一个正整数,请编写一个程序,将x分解为若干个素数的乘积。
#include <bits/stdc++.h>
using namespace std;
int num[10000],c,n,t;
int main()
{
scanf("%d",&t); //t组测试数据
while(t--)
{
scanf("%d",&n);
c = 0;
for(int i = 2; i < = n; i++)
{
while(n%i==0)//有了这个循环 就不必求素数表了,为啥呢,自己想啊
{
num[c++]=i;
n/=i;
}
}
for(int i = 0; i < c; i++)
{
printf(i==0?"%d":"*%d",num[i]);
}
printf("\n");
}
return 0;
}
(待更新)
3.判断素数
定义判断是否有多余的因数即可即可,但是你认为需要从1判断到这个数本身吗?
当然不必,判断到即可,为什么呢,因为大于的数根本不可能被整除。
代码:
//判断是否是一个素数
int IsPrime(int x)
{
if(x<=1) //0,1,负数都是非素数
return 0;
int ans=(int)sqrt(x)+1; /*计算枚举上界,为防止ans值带来的精度损失,所以采用根号值
取整后再加1,即宁愿多枚举一个,也不愿少枚举一个数 */
for(int i=2; i<ans; i++)
{
if(x%i==0)
{
return 0;//只要一个被整除,就不是素数
}
}
return 1;
}
4.素数筛法:
先开一个比较大的数组prime[ ]奇数下标的标为true(1除外),偶数下标标为false(2除外)
for( i=3; i<=sqrt(n); i+=2 )
{
if(prime[i])
for( j=i+i; j<=n; j+=i )//素数的任意倍数都必然是合数
prime[j]=false;
}
线性筛法:
/*
遇到素数需要打表时,先估算素数的个数:
num = n / lnx;
num为大概数字,越大误差越小(只是估计,用于估算素数表数组大小)
线性筛法wwwww
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 10010000
int n;
bool visit[maxn];
int prime[maxn];
void isprime()
{
memset(visit, true, sizeof(visit));
int num = 0;
for (int i = 2; i <= n; ++i)
{
if (visit[i] == true)
{
num++;
prime[num] = i;
}
for (int j = 1; ((j <= num) && (i * prime[j] <= n)); ++j)
{
visit[i * prime[j]] = false;
if (i % prime[j] == 0) break; //深究之处!
}
}
}
int main()
{
memset(prime, 0, sizeof(prime));
int count= 0;
scanf("%d",&n);
isprime();
for(int i = 0; i <= n; ++i)
if(prime[i])
{
printf("%d ",prime[i]);
count++;
}
printf("\n");
printf("the sum of prime num is:%d\n",count);
return 0;
}