Простое число выше 6 миллионов

Я решал вопрос в Hackerrank, и вопрос заключался в том, чтобы найти количество простых чисел в диапазоне. Поскольку при использовании обычной методологии меня ждал тайм-аут, я использовал Решето Эратосфена. Большинство тестовых наборов работали, кроме двух скрытых тестовых наборов. Я запустил код в компиляторе GDB и выяснил, что код поддерживает только значения до 6 миллионов. Что я делаю? Код приведен ниже:

#include<cstring>
#include<cstdio>
#include <iostream>
#include <algorithm>
using namespace std;


void SieveOfEratosthenes(unsigned long long int a,unsigned long long int b) 
{ 
    unsigned long long int count=0; 
    bool prime[b+1]; 
    memset(prime, true, sizeof(prime)); 
  
    for (unsigned long long int p=2; p*p<=b; p++) 
    { 
        // If prime[p] is not changed, then it is a prime 
        if (prime[p] == true) 
        { 
            for (unsigned long long int i=p*p; i<=b; i += p) 
                prime[i] = false; 
        } 
    } 
  
    for (unsigned long long int p=a; p<b; p++) 
       if (prime[p] &&p!=1) 
           count++;
    cout<<count;
          
} 
  
int main() 
{ 
    unsigned long long int a,b;
    cin>>a>>b;
    SieveOfEratosthenes(a,b); 
    return 0; 
} 

person Anand Sasidharan    schedule 03.08.2020    source источник
comment
что не работает для чисел больше 6 миллионов?   -  person 463035818_is_not_a_number    schedule 03.08.2020
comment
может быть, это не проблема, но bool prime[b+1]; не является стандартным С++. Почему массивы переменной длины не являются частью C++ стандартный?   -  person 463035818_is_not_a_number    schedule 03.08.2020
comment
Возможно, вы переполняете стек функций, вы можете использовать вектор вместо логического массива bool prime[b+1];   -  person Deepak Patankar    schedule 03.08.2020
comment
Массив размером 6 миллионов логических значений (каждый размером 1 байт) составляет около 6 МБ размера стека. Вы почти наверняка превысили лимит стека.   -  person freakish    schedule 03.08.2020
comment
Я хочу спросить одну вещь: вам нужно отвечать на несколько запросов, содержащих a и b?   -  person brc-dd    schedule 03.08.2020
comment
Попробуйте bool prime[b+1] -> static bool prime[b+1] . Если это работает, то это проблема размера стека, как упоминалось в предыдущих комментариях.   -  person Jabberwocky    schedule 03.08.2020


Ответы (2)


Похоже на классическое переполнение стека. bool prime[b+1]; выделено в стеке, и вы достигли предела.

Если это работает в Linux, то максимально допустимый размер стека обычно составляет около 8 МБ или меньше, поэтому есть большая вероятность, что вы только что превысили это значение.

Переместите его из стека или выполните битовую упаковку вместо полного bool, и он снова должен работать нормально.

person Ext3h    schedule 03.08.2020

Вы создаете логический массив в своей функции, который будет храниться в стеке. В Windows типичный максимальный размер стека составляет 1 МБ, тогда как в типичном современном Linux он составляет 8 МБ. Вы создаете массив с 6 миллионами записей, который будет составлять почти 6 МБ.

Чтобы решить эту проблему, вы можете создать vector вместо массива, который будет хранится в куче.

person Deepak Patankar    schedule 03.08.2020
comment
небольшая придирка: вектор может быть в стеке, но его данные в куче - person 463035818_is_not_a_number; 03.08.2020
comment
vector<bool> может иметь некоторые незначительные проблемы, потому что это единственный упакованный векторный класс, но в данном случае это преимущество. Это будет всего 750 КБ для 6 миллионов логических значений, и действительно вектор сам выделит эти 750 КБ из кучи. - person MSalters; 03.08.2020
comment
Спасибо @idclev463035818 за предложение, я добавил ссылку, которая глубоко объясняет концепции, на которые вы ссылаетесь. - person Deepak Patankar; 03.08.2020
comment
Спасибо @MSalters, я не понял, как это займет всего 750 КБ, не могли бы вы объяснить? - person Deepak Patankar; 03.08.2020
comment
@DeepakPatankar: std::vector<bool> не имеет внутреннего представления как bool[], поэтому std::vector<bool>::data() отсутствует. Вместо этого он хранит 8 логических значений на байт. 6 миллионов / 8 = 750 000. - person MSalters; 03.08.2020
comment
@MSalters Теперь я понял, большое спасибо за объяснение !!! - person Deepak Patankar; 03.08.2020