В этой статье блога мы углубимся в алгоритм «Решето Сундарама», алгоритм генерации простых чисел, названный в честь индийского математика С.П. Сундарама. Мы обсудим его временную сложность и рассмотрим различные реализации алгоритма на разных языках программирования. К концу этой статьи вы получите хорошее представление об эффективности алгоритма и о том, как его можно реализовать в коде.
Что такое решето Сундарама:
Решето Сундарама — это древний алгоритм, используемый для генерации простых чисел до заданного предела. Он работает путем исключения чисел вида i + j + 2ij, где 1 ≤ i ≤ j и i + j + 2ij ≤ n. Остальные числа, удвоенные и увеличенные на единицу, дают простые числа.
Анализ временной сложности.
Временную сложность алгоритма «Решето Сундарама» можно проанализировать следующим образом:
-
Создание массива. Первый шаг включает создание массива размером (n-1)/2. Эта операция занимает время O(n).
-
Устранение непростых чисел. Алгоритм исключает числа вида i + j + 2ij до заданного предела n. Число итераций, необходимых для исключения этих чисел, составляет примерно n/2. На каждой итерации нам нужно пометить все кратные текущему числу, что занимает время O(n). Таким образом, общая временная сложность этого шага равна O(n^2).
-
Подсчет простых чисел. После исключения непростых чисел мы подсчитываем оставшиеся простые числа. Этот шаг занимает время O(n), так как нам нужно один раз пройтись по массиву, чтобы подсчитать простые числа.
Учитывая эти шаги, общая временная сложность алгоритма Решета Сундарама составляет O(n^2).
Реализации на разных языках программирования.
Теперь давайте рассмотрим примеры кода алгоритма Sieve of Sundaram на разных языках программирования.
-
Python:
def sieve_of_sundaram(n): k = (n - 2) // 2 primes = [True] * (k + 1) for i in range(1, k + 1): j = i while i + j + 2 * i * j <= k: primes[i + j + 2 * i * j] = False j += 1 prime_numbers = [2] + [(2 * i + 1) for i in range(1, k + 1) if primes[i]] return prime_numbers -
Java:
import java.util.ArrayList; import java.util.List; public class SieveOfSundaram { public static List<Integer> sieveOfSundaram(int n) { int k = (n - 2) / 2; boolean[] primes = new boolean[k + 1]; List<Integer> primeNumbers = new ArrayList<>(); for (int i = 1; i <= k; i++) { int j = i; while (i + j + 2 * i * j <= k) { primes[i + j + 2 * i * j] = true; j++; } } primeNumbers.add(2); for (int i = 1; i <= k; i++) { if (!primes[i]) { primeNumbers.add(2 * i + 1); } } return primeNumbers; } }
Это всего лишь два примера, но алгоритм «Решето Сундарама» может быть реализован и на других языках программирования.
Алгоритм «Решето Сундарама» — это эффективный метод генерации простых чисел до заданного предела. Хотя его временная сложность равна O(n^2), он все же может быть практичным выбором для относительно небольших значений n. Мы рассмотрели примеры кода на Python и Java, но вы можете реализовать этот алгоритм и на других языках. Понимание временной сложности алгоритмов помогает нам принимать обоснованные решения при выборе наиболее подходящего алгоритма для наших нужд.