如何更有效地检查数字是否为质数?

时间:2018-06-19 14:31:35

标签: c++ primes

所以我有以下问题。他们给了我一个带n个数字的数组,如果使用“ Divide et Impera”包含任何质数,我必须打印。我解决了这个问题,但由于效率不高(他们说),它只能得到70/100。

#include <iostream>
using namespace std;

bool isPrime(int x){
   if(x == 2) return false;
   for(int i = 2; i <= x/2; ++i)
      if(x%i==0) return false;
   return true;

}

int existaP(int a[], int li, int ls){
    if(li==ls)
       if(isPrime(a[li]) == true) return 1;
       else return 0;
    else  return existaP(a, li, (li+ls)/2)+existaP(a, (li+ls)/2+1, ls);      
}

int main(){
   int n, a[10001];
   cin >> n;
   for(int i = 1; i<=n; ++i) cin >> a[i];
   if(existaP(a,1,n) >= 1) cout << "Y";
   else cout << "N";
   return 0;
}

7 个答案:

答案 0 :(得分:4)

这里挂得最少的水果是您有条件的停止

i <= x/2

可以替换为

i * i <= x

务必确保您不会溢出int。这是因为您只需要上移到x的平方根,而不是一半。

由于返回值不正确,因此x == 2的算法也有缺陷。如果您放弃了该额外的测试,那就更好了,因为随后的循环将覆盖它。

答案 1 :(得分:1)

一种标准的方法(也许是..?)只是从i = 0到sqrt(number)进行检查

app.route

答案 2 :(得分:0)

如果n为1,您的代码将给出错误的答案。

您的时间复杂度可以降低为 sqrt(n),其中 n是数字

这是代码

bool isPrime(long int n)
{
  if (n == 1)
  {
    return false;
  }
  int i = 2;
  while (i*i <= n)
  {
      if (n % i == 0)
      {
          return false;
      }
      i += 1;
  }
  return true;
}

“长整数”将有助于避免溢出。

希望这会有所帮助。 :-)

答案 3 :(得分:0)

如果数字不是太大,您也可以尝试使用Eratosthenes筛子解决此问题:

#include <iostream>
#include <array>

using namespace std;
constexpr int LIMIT = 100001;
// not_prime because global variables are initialized with 0
bool not_prime[LIMIT];

void sieve() {
    int i, j;
    not_prime[2] = false;

    for(int i = 2; i < LIMIT; ++i) 
        if(!not_prime[i])
            for(int j = i + i; j < LIMIT; j += i) 
                not_prime[j] = true;
}

int existaP(int a[], int li, int ls){
    if(li==ls)
       if(!not_prime[a[li]] == true) 
           return 1;
       else  
           return 0;
    else   
           return existaP(a, li, (li + ls) / 2) + existaP(a, (li + ls) / 2 + 1, ls);      
}

int main(){
   int n, a[10001];
   cin >> n;
   for(int i = 1; i<=n; ++i) cin >> a[i];

   sieve();

   if(existaP(a,1,n) >= 1) cout << "Y";
   else cout << "N";
   return 0;
}

基本上,当您遇到质数时,所有倍数都不是质数。

P.S .: Acum am vazut ca esti roman :) 最适合您的算法:https://infoarena.ro/ciurul-lui-eratostene

答案 4 :(得分:0)

existaP(a, li, (li+ls)/2) + existaP(a, (li+ls)/2+1, ls);

是另一个尚未提及的效率低下的问题

尤其是这里的问题是+。如果您知道existaP(a, li, (li+ls)/2)> 0,那么existaP(a, (li+ls)/2+1, ls)不再重要。换句话说,您目前正在计算确切个唯一因素的数量,但是一旦您知道一个数字具有至少两个因素,就知道它不是素数。

答案 5 :(得分:0)

这是一种检查给定数字是否为素数的有效方法。

{{1}}

答案 6 :(得分:0)

这是检查质数的有效方法。

 bool isPrime(int num) {
        if(num <= 1) return false;
        if (num <= 3)  return true; 
        
        int range = sqrt(num);
        // This is checked so that we can skip 
        // middle five numbers in below loop 
        if (num % 2 == 0 || num % 3 == 0) 
            return false; 
        

        for (int i = 5; i <= range; i += 6) 
            if (num % i == 0 || num % (i + 2) == 0) 
                return false; 
        
        return true;
    }