Алгоритм простых коэффициентов: C, Python Пример

⚡ Умное резюме

Алгоритм разложения на простые множители разлагает любое положительное целое число на произведение простых чисел с помощью пробного деления до квадратного корня или варианта решета Эратостена, который хранит каждый наименьший простой множитель.

  • 🧮 Определение: Простые множители целого числа — это простые числа, произведение которых равно ему; число 10 делится на 2 и 5.
  • 🔁 Отдел судебных разбирательств: Итерация от 2 до sqrt(n) с делением всякий раз, когда модуль равен нулю, выполняется за время O(sqrt(n)).
  • 🧰 Метод сита: Сохранение наименьшего простого множителя для каждого значения с точностью до определенного предела сокращает время факторизации примерно до O(log n) на запрос.
  • 🐍 Python Code: Итеративный и рекурсивный Python Реализации выводят каждый простой множитель введенного числа.
  • 💻 C Code: В сопоставимых итеративных и рекурсивных программах на языке C демонстрируется одна и та же логика с использованием стандартного ввода-вывода и предварительно вычисленного массива.
  • 🔐 Применение: Разложение на простые множители позволяет проверять делимость, упрощать дроби, находить общие знаменатели и создавать криптографические ключи на основе чисел.

Алгоритм простого фактора

Что такое простая факторизация?

Простой делитель числа — это делитель, который сам является делителем. простое число, делится только на 1 и на себя.

Пример: Простыми множителями числа 10 являются 2 и 5, поскольку 2 × 5 = 10.

Нахождение простых множителей с помощью итерации

Проходим итерации от 2 до sqrt(n) и проверяем делимость. Пока n делится на текущий кандидат, делим и выводим результат.

Пример: каждое простое число больше 40 подходит для n2+n+41, следовательно, n = 0, 1, 2 дает 41, 43, 47.

Как напечатать простой делитель числа?

  • Производить итерации чисел от 2 до sqrt(n).
  • Проверьте остаток от деления числа n на множитель каждого из кандидатов; нулевой остаток означает, что кандидат является простым множителем.
  • Соберите все простые числа, которые делят n.
  • Данная процедура выполняется за время O(sqrt(n)).

Алгоритм:

Set a counter i to 2
While i <= sqrt(n):
    While n % i == 0:
        n = n / i
        print i
    i = i + 1
if n > 1:
    print n

Алгоритм сита

Метод решета сохраняет наименьший простой множитель каждого числа до максимального предела, что значительно снижает затраты на факторизацию после предварительных вычислений.

  • Запишите наименьший простой множитель каждого целого числа до максимального предела.
  • Возьмите наименьшее простое число и добавьте его к множеству множителей.
  • Разделите полученное число на это простое число и повторяйте, пока не получите 1.
  • Каждый запрос выполняется примерно за O(log n).

Пример: Любое простое число, кроме 2 и 3, соответствует виду 6n-1 или 6n+1. Например, 5 = 6(1)-1 и 19 = 6(3)+1.

Алгоритм: определить массив Этот модуль хранит наименьший простой множитель каждого числа, используя индекс в качестве начального значения для каждого элемента.

Set array[1] to 1
Set i to 2
While i*i <= max_number:
    If array[i] == i:
        Set j to i*i
        While j <= max_number:
            If array[j] == j:
                array[j] = i
            j = j + i
    i = i + 1
while the_number != 1:
    print array[the_number]
    the_number = the_number / array[the_number]

Статьи по теме

Python Основные множители с использованием итерации

Следующие Python Код находит простые множители, используя итеративный метод пробного деления:

import math
def PrimeFactors(n):
    for i in range(2, int(math.sqrt(n)) + 1, 1):
        while n % i == 0:  # find all the occurrences of a prime factor
            print((int)(i))
            n = n // i
    if n != 1:  # if the number was originally a prime
        print((int)(n))
n = (int)(input("Enter the number you want: "))
PrimeFactors(n)

Выход:

Enter the number you want: 4
2
2

Python Простые множители с использованием рекурсии

Python Приведённый ниже код использует метод решета для нахождения простых множителей заданного числа.

import math
High = (int)(1e5 + 7)
array = [0 for i in range(High)]

# generate smallest prime factors
def Sieve():
    for i in range(1, High):
        array[i] = i
    for i in range(2, math.ceil(math.sqrt(High))):
        if array[i] == i:
            for j in range(i * i, High, i):
                if array[j] == j:
                    array[j] = i

def PrimeFactors(n):  # divide until we reach 1
    if n == 1:
        return
    print((int)(array[n]))
    PrimeFactors((int)(n / array[n]))

Sieve()
n = (int)(input("Enter the number you want: "))
PrimeFactors(n)

Выход:

Enter the number you want: 4
2
2

Программа C Prime Factors с использованием итерации

То же самое итерационное решение, записанное на CВведите число, затем для каждого кандидата от 2 до sqrt(n) проверьте делимость и выведите каждое вхождение простого множителя.

#include <stdio.h>
int main()
{
    int n;
    printf("Enter the number you want: ");
    scanf("%d", &n);
    for (int i = 2; i * i <= n; i++)
    {
        while (n % i == 0)  // find all the occurrences of a prime factor
        {
            printf("%d\n", i);
            n /= i;
        }
    }
    if (n != 1)  // if the number was originally a prime
    {
        printf("%d", n);
    }
    return 0;
}

Выход:

Enter the number you want: 2
2

Программа C Prime Factors с использованием рекурсии

Программа C Prime Factors с использованием рекурсии

Рекурсивная версия на языке C повторяет Python первый шаг: составить массив наименьших простых множителей, затем рекурсивно делить на этот множитель до тех пор, пока n не достигнет 1.

#include <stdio.h>
int Max = 100007;
int array[100007];

void Sieve()  // smallest prime factors up to Max
{
    for (int i = 1; i < Max; i++)
        array[i] = i;
    for (int i = 2; i * i <= Max; i++)
    {
        if (array[i] == i)
        {
            for (int j = i * i; j < Max; j += i)
            {
                if (array[j] == j)
                    array[j] = i;
            }
        }
    }
}

void PrimeFactors(int n)
{
    if (n == 1)  // divide until we reach 1
        return;
    printf("%d\n", array[n]);
    PrimeFactors(n / array[n]);
}

int main()
{
    Sieve();
    int n;
    printf("Enter the number you want: ");
    scanf("%d", &n);
    PrimeFactors(n);
    return 0;
}

Выход:

Enter the number you want: 2
2

Несколько интересных фактов о простых числах

  • Любое четное число, кроме 2, можно представить как сумму двух простых чисел (4 = 2 + 2, 6 = 3 + 3, 8 = 5 + 3).
  • Кроме 2 и 3, нет других последовательных простых чисел, поскольку 2 — единственное четное простое число.
  • Все простые числа, кроме 2 и 3, имеют вид 6n + 1 или 6n − 1, где n — положительное целое число.
  • Множество простых множителей числа является единственным.
  • Число 1 не является ни простым, ни составным.
  • Разложение на простые множители помогает в решении задач на делимость, упрощении дробей и нахождении общих знаменателей.
  • Разложение на простые множители также лежит в основе числовых криптографических кодов.

Часто задаваемые вопросы (FAQ)

Разложение на простые множители разлагает целое число на произведение простых чисел, например, 12 = 2 × 2 × 3. Простые множители уникальны для каждого целого числа больше единицы.

Если n имеет множитель больше sqrt(n), то его пара меньше и уже будет найдена. Все, что находится после sqrt(n), повторяется.

Метод пробного деления выполняется за O(sqrt(n)). Метод решета предварительно вычисляет наименьшие простые множители за O(N log log N), а затем отвечает на каждое разложение примерно за O(log n).

Используйте решето при разложении на множители множества чисел в пределах известной верхней границы. Одно предварительное вычисление позволяет выполнять каждый последующий запрос примерно за O(log n).

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

Разложение на простые множители лежит в основе проверок на делимость, упрощения дробей, вычисления НОК и НОД, а также криптографии с открытым ключом, такой как RSA, где разложение на множители большого произведения двух простых чисел представляет собой сложную задачу.

Системы искусственного интеллекта применяют разложение на простые множители к теоретико-числовым характеристикам, анализу криптографических ключей и безопасному федеративному обучению. Постквантовые исследования в области машинного обучения также изучают устойчивость к факторизации.

Да. GitHub Copilot и аналогичные ИИ-помощники автоматизируют стандартный код для алгоритмов пробного деления и решета, хотя разработчики по-прежнему проверяют сложность и граничные случаи, такие как n = 1.

Подведем итог этой публикации следующим образом: