博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
素数判断
阅读量:4344 次
发布时间:2019-06-07

本文共 2623 字,大约阅读时间需要 8 分钟。

介绍

    素数又称质数,既只能被1和它本身除尽的自然数。也就是说素数只有1和它本身两个约数,它只能表示为1和它本身的乘积。

 

 

原理

    使用一个for循环分别将需要判断的数(number)和2到number-1进行取余运算,如余数为0则表示可以除尽。当number不能被2到number-1的任何一个数除尽的时候,则number为素数,否则则不为素数。

 

void main()

    {
       int i = 0;
     int a[10] = {5,4,9,8,7,6,0,1,3,2}; // 也可以是用scanf方法得到需要判断的数
     for(i = 0; i < 10; i++)
     {
     if(judgeprime(a[i])) // 调用素数判断函数
     printf("%d是素数. ", a[i]);
     else
     printf("%d不是素数. ", a[i]);
     }
    }

 

算法1 复杂度O(n*log(n))

 

#include <iostream>
using
namespace
std;
  
bool
isPrime(
int
nr)
{
    
for
(
int
d = 2; (d * d) < (nr + 1); ++d){
        
if
(!(nr % d)){
            
return
false
;
        
}
     
}
    
return
true
;
}
  
int
main (
int
argc,
char
*
const
argv[])
{
    
for
(
int
i = 0; i < 50; ++i){
        
if
(isPrime(i)){
            
cout << i << endl;
        
}
    
}
}

算法2 复杂度O(n(log(logn)))采用排除法的方式

 

示例:打印30以内的质数

一、初始化如下列表。

2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

二、把第一个数(2)取出来,去掉所有可以被2整除的数。

2  3     5     7     9    11    13    15    17    19    21    23    25    27    29

三、取第二个数(3),去掉所有可以被 3整除的数。

2  3     5     7          11    13          17    19          23    25          29

四、取第三个数(5),因为4已经被去除了,再去掉所有可以被5整除的数。

2  3     5     7          11    13          17    19          23                29

接下来的数是7,但是7的平方是49,其大于了30,所以我们可以停止计算了。剩下的数就是所有的质数了。

算法3.O(log(n))或是O(1)的时间复杂度

把质数事先就计算好,放在一个文件中,然后在程序启动时(注意是在启动时读这个文件,而不是运行时每调用一次就读一次文件),读取这个文件,然后打印出来就可以了。如果需要查找的化,二分查找或是hash表查找将会获得巨大的性能提升。

算法4。

使用编译时而不是运行时

template
<
int
N,
int
D = N - 1>
struct
isPrime {
    
enum
{
        
result = (N % D) && isPrime<N, D-1>::result
    
};
};
  
template
<
int
N>
struct
isPrime<N, 1> {
    
enum
{
        
result =
true
    
};
};

于是,通过这个模板,我们可以使用下面的代码来检查是否是质数:

1
2
if
(isPrime<3>::result)
    
cout <<
"Guess what: 3 is a prime!"
;

下一步,我们需要打出一个区间内的质数,所以,我们需要继续设计我们的print模板。

1
2
3
4
5
6
7
8
9
10
11
template
<
int
N,
bool
ISPRIME>
struct
printIfPrime {
    
static
inline
void
print() {}
};
  
template
<
int
N>
struct
printIfPrime<N,
true
> {
    
static
inline
void
print() {
        
std::cout << N << endl;
    
}
};

从上面的代码中,我们可以看到,我们的第一个实际是什么也没做,而第二个有输出,注意第二个的模板参数中有一个true,其意味着那个质数的判断。于是我们就可以给出下面的代码来尝试着打印出一段区间内的质数:(请不要编译!!因为那会让编译器进入无限循环中,原因是printPrimes会不停地调用自己永不停止)

1
2
3
4
5
6
7
8
template
<
int
N,
int
MAX>
struct
printPrimes {
    
static
inline
void
print()
    
{
        
printIfPrime<N, isPrime<N>::result>::print();
        
printPrimes<N + 1, MAX>::print();
    
}
};

为了避免这个问题,你需要再加一个模板类,如下所示。这样当N变成MAX的时候,递归就结束了。

1
2
3
4
5
6
template
<
int
N>
struct
printPrimes<N, N> {
    
static
inline
void
print() {
        
printIfPrime<N, isPrime<N>::result>::print();
    
}
};

最后,让我们来看看最终的调用:

1
2
3
4
5
int
main (
int
argc,
char
*
const
argv[])
{
    
printPrimes<2, 40>::print();
    
return
0;
}

这个方法很NB,但是有两个问题:

  • 比较耗编译时间。
  • 不能在运行时输入MAX的值。

 

转载于:https://www.cnblogs.com/lqc1002000/archive/2012/06/04/2535334.html

你可能感兴趣的文章
在 Linux 下使用 水星MW150cus (RTL8188CUS芯片)无线网卡
查看>>
JavaScript中的方法重载
查看>>
Js中变量的作用域
查看>>
sql--截取字段中的部分数据
查看>>
linux 遇到(vsftpd)—500 OOPS:chroot
查看>>
[Eigen]C++开源线代库
查看>>
java实现简单的单点登录
查看>>
GIS学习之栅格数据
查看>>
C# model代码生成器
查看>>
NCO3部署到服务器后无法连接到SAP
查看>>
Eclipse Debug
查看>>
CodeForces 149D Coloring Brackets
查看>>
[转]PLSQL Developer备份恢复oracle数据
查看>>
[转]C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
查看>>
3.23课·········格式与布局
查看>>
TCP/IP——ARP与RARP简记
查看>>
python(七) Python中单下划线和双下划线
查看>>
JavaScript入门二
查看>>
form 转json,将form表单中的数据序列化数组后转换为Json
查看>>
《JAVA与模式》之抽象工厂模式
查看>>