Детальный Скрининг простой метод скрининга Эриксена (C ++, чтобы достигнуть)

Описание: Часть п и N имеют тот же смысл, но чувствителен к выполнению специфических и только общей форме, так что читатель может перемежаться с заблуждением, как и его понимание.

А, определяются простое число

Относится к целое число больше 1, ее можно разделить на число 1 и само по себе.

Во-вторых, самое главное Эриксена скрининг вывод:

Н имеет фактор, то есть по крайней мере, одним из факторов не более половины N \ SQRT {N} ,
Например, 100 не оценивается как простое число, 100 = 10 х 10, до тех пор , пока существует фактор> 100 \ SQRT {100} Bound ниже коэффициента < 100 \ SQRT {100} , До тех пор , как наличие или отсутствие может быть определено в пределах коэффициента 10 100, чтобы использовать этот метод временной сложности O (N * √n).
Таким образом , вы не можете действительно понять, читайте дальше.

В-третьих, найти [0, п] алгоритм Основная идея диапазона всех простых чисел

  1. Во-первых 0,1 исключить:

  2. Создать список последовательных целых чисел от 2 до п, [2,3,4, ..., п];

  3. Инициализация р = 2, так как 2 наименьшее простое число;

  4. Перечислять все кратное р (2р, 3р, 4р, ...), маркированного как не простые числа (номера вместе);

  5. Найдите тег и без числа р больше, чем один. Если нет, то конец операции, если, учитывая значения р, повторите шаги 4;

  6. После операции все остальные немаркированных простое число найдено.

Это может быть объединено с подвижнымами фиг оценены ниже:
Here Вставка рисунка Описание

В-четвертых, оптимизированные прикладные идеи Эриксена скрининга

Мы нашли [0, N] в пределах партии> N \ SQRT {N} На самом деле, это число [0, N \ SQRT {N} ] Multiple числа диапазона. > N \ SQRT {N} И не [0, N \ SQRT {N} , Кратна простого числа] диапазона чисел.
Например: [0, 100] Многие в диапазоне> 100 \ SQRT {100} На самом деле, это число [0, 100 \ SQRT {100} Диапазон кратные] число (12,14,16 кратно 2, 3, ... оно кратно 12,15,18). > 100 \ SQRT {100} И не [0, 100 \ SQRT {100} (11,13,17 ...), кратные простые числа в пределах] диапазона чисел.

Таким образом , мы делаем следующие основные алгоритмов для оптимизации титульных три идей:
Для шага 4, вы не можете начать исключать из 2ра, а непосредственно из п 2 р ^ 2 запуска. В начале причин уже упоминалось, все меньше п 2 р ^ 2 количество сопутствующих факторов меньше исключены.

На шаге 5, когда п 2 р ^ 2 Расчет> н-время остановлен.


Ссылка ссылка:
«Использование Эратосфена метода скрининга , чтобы быстро найти простые числа в 2,1 млрд»
«Эратосфен простого числа скрининга Решения проблем»


Int диапазон, когда диапазон:

#include<iostream>
#include<cstdio>
using namespace std;
    
const int maxn=5000000;
long prime[maxn];    // 存储一个个确定为质数的数
bool is_prime[maxn+1];    // 标记范围内所有数
int p = 0;
int sieve(int n)
{
 	p = 0;
	for(int i=0;i<=n;i++)
		is_prime[i]=true;       // 所有数先标记为true
    is_prime[0] = is_prime[1] = false;   // 把数字0,1标记为质数
    for(int i=2;i<=n;i++)
    {
       	if(is_prime[i])         // 如果这个数没有被标记为false
    	{
             prime[p++]=i;       // 用prime数组存起来这个数,既存起了质数,又用p表示了质数个数
             for(int j=i*i;j<=n;j+=i)   // 这里没有优化时的写法是for(int j=2*i; j<=n; j++)。
	    	//因为小于j(即i^2)内的合数都因为(根号j)(即i)内有更小的j的的因数而被排除
    							// 比如3^2 = 9,为什么不算2*3 = 6呢, 因为6<9,所以6因为3以内有更小的因数而直接被排除
    				is_prime[j]=false;
        }
    }
    return p;          // 返回质数个数
}
int main()
{
	int n;
	while(~scanf("%d",&n))
    {
    	printf("质数个数是: %d\n",sieve(n));
    	printf("质数有:\n");
    	for (int i = 0; i<p; i++)
    	{
    		printf("%d ", prime[i]);
    		printf("\n\n");
        }
   	}
    system("pause");
}	

Если диапазон превышает Int

static const int N = 1e7;
bool is_prime[N];   // 判断是否是素数
ll prime[N];       // 存储素数
ll sieve(ll num)
{
	int inx = 0;
	for (int i = 0; i<=N; i++)
		is_prime[i] = true;

	is_prime[0] = is_prime[1] = false;

	int MIN = (num > N) ? N : num;

	for (ll i = 2; i<=MIN; i++)
	{
		if (is_prime[i])
		{
			prime[inx++] = i;

			for (ll j = i*i; j<=num; j+=i)
				is_prime[j] = false;
		}
	}
	return inx;
}

int gcd(int inx)    // 此处由于传进来都是质数,所以直接相乘即为gcd
{
	int res = 1;
	for (int i = 0; i<inx-1; i++)
		res *= prime[i];
	return res;
}

void C3()
{
	ll num;     // 输入数
	int p;       // 最小公约数

	cin >> num;

	int inx = sieve(num);   // 筛选素数

	cout << gcd(inx) << endl;
}
Опубликовано 131 оригинальные статьи · вона похвала 81 · просмотров 60000 +

рекомендация

отblog.csdn.net/weixin_43469047/article/details/104752705
рекомендация