0
点赞
收藏
分享

微信扫一扫

论如何对暴力素数算法进行简单优化

登高且赋 2022-07-27 阅读 45

简介

论如何对暴力素数算法进行简单优化_#include

这是之前发的一道简单的PAT题目–​​数素数(PAT1013)​​,由于这道题官方要求的素数范围极小,所以暴力遍历即可解决。

素数暴力求法(未优化)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <cmath>

using namespace std;

int prime[10005];

bool isPrime(int i)
{
for(int j = 2; j <= (int)sqrt(i); j++)
{
if(i % j == 0)
{
return false;
}
}
return true;
}

int main(void)
{
int num = 0;
int i = 0;
int begin = 0, end = 0;
int count = 1;
memset(prime, 0, sizeof(prime));
scanf("%d %d", &begin, &end);
for(i = 2;; i++)
{
if(num == end)
{
break;
}
if(isPrime(i))
{
prime[num++] = i;
}
}
for(i = begin - 1; i <= end - 1; i++)
{
if(count % 10 != 0)
{
if(i == end - 1)
{
printf("%d", prime[i]);
break;
}
printf("%d ", prime[i]);
count++;
}
else
{
printf("%d\n", prime[i]);
count++;
}
}
return 0;
}

经过优化后,我们在3之后只求奇数,让目标奇数只与之前求过的素数取余,且把遍历素数范围控制在sqrt(已求素数总数)范围内。

优化后的暴力代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <cmath>

using namespace std;

int prime[10005];

int main(void)
{
int num = 2;
int i = 0, j = 0;
int begin = 0, end = 0;
int count = 1;
memset(prime, 0, sizeof(prime));
scanf("%d %d", &begin, &end);
prime[0] = 2;
prime[1] = 3;
for(i = 5; ; i += 2) //只求奇数
{
if(num >= end)
{
break;
}
for(j = 0; j <= (int)sqrt(num); j++) //缩减循环次数
{
if(i % prime[j] == 0) //与之前已经求过的prime数组中的数取余
{
break;
}
else
{
if (j + 1 > (int)sqrt(num))
{
prime[num++] = i;
break;
}
}
}
}
for(i = begin - 1; i <= end - 1; i++)
{
if(count % 10 != 0)
{
if(i == end - 1)
{
printf("%d", prime[i]);
break;
}
printf("%d ", prime[i]);
count++;
}
else
{
printf("%d\n", prime[i]);
count++;
}
}
return 0;
}

优化后的算法遍历大规模素数的时间是原算法的一半。

测试

  • 优化前
  • 论如何对暴力素数算法进行简单优化_ios_02

  • 优化后
  • 论如何对暴力素数算法进行简单优化_ios_03



举报

相关推荐

0 条评论