Гид по технологиям

Как вычислить nPr — перестановки

4 min read Алгоритмы Обновлено 05 Jan 2026
nPr — перестановки: формула и примеры
nPr — перестановки: формула и примеры

Перестановки: иллюстрация упорядоченных расположений элементов

Перестановка — это расположение объектов, в котором важен порядок выбора. В этой статье объяснено, как вычислить значение nPr и приведены реализации на Python, C++, JavaScript, C и Java.

Формула и объяснение

Используйте следующую формулу перестановок:

nPr = (n!)/(n-r)!

Где:

n = общее количество элементов  
P = перестановка  
r = число выбираемых элементов  
! = факториал

Ключевая идея (умственная модель): nPr — это количество упорядоченных выборок длины r без повторений; это эквивалентно перемножению r чисел от n вниз.

Проблема

Даны значения n и r. Нужно вычислить nPr.

Примеры:

  • Пример 1: n = 10, r = 5. nPr = 10! / 5! = 30240.
  • Пример 2: n = 3, r = 2. nPr = 3! / 1! = 6.
  • Пример 3: n = 8, r = 0. nPr = 8! / 8! = 1.

Быстрый способ вручную (мини-метод)

  1. Если r == 0 → ответ 1.
  2. Если r > n или r < 0 → некорректные данные (обработать как ошибку).
  3. Вычислить произведение: n (n-1) … * (n-r+1).
  4. Использовать целые типы đủ большой ёмкости (long long / BigInteger) или библиотеки для больших чисел.

Важно: не вычисляйте n! и (n-r)! полностью, если n велико — это приводит к переполнению и лишней работе.

Примеры программ (с сохранением исходных реализаций)

C++ Программа для вычисления nPr

// C++ program to calculate the value of nPr  
#include   
using namespace std;  
  
// Function to calculate the factorial of a number  
int factorial(int num)  
{  
 if (num<=1)  
 {  
 return 1;  
 }  
 return num*factorial(num-1);  
}  
  
// Function to calculate the value of nPr  
int calculate_nPr(int n, int r)  
{  
 return factorial(n) / factorial(n - r);  
}  
  
  
int main()  
{  
 int n1 = 10;  
 int r1 = 5;  
 cout << "n: " << n1 << ", r: " << r1 << endl;  
 cout << "Value of nPr: " << calculate_nPr(n1, r1) << endl;  
  
 int n2 = 3;  
 int r2 = 2;  
 cout << "n: " << n2 << ", r: " << r2 << endl;  
 cout << "Value of nPr: " << calculate_nPr(n2, r2) << endl;  
  
 int n3 = 1;  
 int r3 = 1;  
 cout << "n: " << n3 << ", r: " << r3 << endl;  
 cout << "Value of nPr: " << calculate_nPr(n3, r3) << endl;  
  
 int n4 = 8;  
 int r4 = 0;  
 cout << "n: " << n4 << ", r: " << r4 << endl;  
 cout << "Value of nPr: " << calculate_nPr(n4, r4) << endl;  
  
 int n5 = 4;  
 int r5 = 4;  
 cout << "n: " << n5 << ", r: " << r5 << endl;  
 cout << "Value of nPr: " << calculate_nPr(n5, r5) << endl;  
  
return 0;  
}

Вывод:

n: 10, r: 5  
Value of nPr: 30240  
n: 3, r: 2  
Value of nPr: 6  
n: 1, r: 1  
Value of nPr: 1  
n: 8, r: 0  
Value of nPr: 1  
n: 4, r: 4  
Value of nPr: 24

Связано: What Is Recursion and How Do You Use It?

Python Программа для вычисления nPr

# Python program to calculate the value of nPr  
  
# Function to calculate the factorial of a number  
def factorial(num):  
    if num<=1:  
        return 1  
    return num*factorial(num-1)  
  
# Function to calculate the value of nPr  
def calculate_nPr(n, r):  
    return factorial(n) // factorial(n - r)  
  
n1 = 10  
r1 = 5  
print("n:", n1, ",r:", r1)  
print("Value of nPr:", calculate_nPr(n1, r1))  
  
n2 = 3  
r2 = 2  
print("n:", n2, ",r:", r2)  
print("Value of nPr:", calculate_nPr(n2, r2))  
  
n3 = 1  
r3 = 1  
print("n:", n3, ",r:", r3)  
print("Value of nPr:", calculate_nPr(n3, r3))  
  
n4 = 8  
r4 = 0  
print("n:", n4, ",r:", r4)  
print("Value of nPr:", calculate_nPr(n4, r4))  
  
n5 = 4  
r5 = 4  
print("n:", n5, ",r:", r5)  
print("Value of nPr:", calculate_nPr(n5, r5))  

Вывод:

n: 10, r: 5  
Value of nPr: 30240  
n: 3, r: 2  
Value of nPr: 6  
n: 1, r: 1  
Value of nPr: 1  
n: 8, r: 0  
Value of nPr: 1  
n: 4, r: 4  
Value of nPr: 24

Связано: How to Find All Factors of a Natural Number in C++, Python, and JavaScript

JavaScript Программа для вычисления nPr

// JavaScript program to calculate the value of nPr  
  
// Function to calculate the factorial of a number  
function factorial(num) {  
 if (num<=1) {  
 return 1;  
 }  
 return num*factorial(num-1);  
}  
  
// Function to calculate the value of nPr  
function calculate_nPr(n, r) {  
 return factorial(n) / factorial(n - r);  
}  
  
var n1 = 10;  
var r1 = 5;  
document.write("n: " + n1 + ", r:" + r1 + "  \n");  
document.write("Value of nPr: " + calculate_nPr(n1, r1) + "  \n");  
  
var n2 = 3;  
var r2 = 2;  
document.write("n: " + n2 + ", r:" + r2 + "  \n");  
document.write("Value of nPr: " + calculate_nPr(n2, r2) + "  \n");  
  
var n3 = 1;  
var r3 = 1;  
document.write("n: " + n3 + ", r:" + r3 + "  \n");  
document.write("Value of nPr: " + calculate_nPr(n3, r3) + "  \n");  
  
var n4 = 8;  
var r4 = 0;  
document.write("n: " + n4 + ", r:" + r4 + "  \n");  
document.write("Value of nPr: " + calculate_nPr(n4, r4) + "  \n");  
  
var n5 = 4;  
var r5 = 4;  
document.write("n: " + n5 + ", r:" + r5 + "  \n");  
document.write("Value of nPr: " + calculate_nPr(n5, r5) + "  \n");

Вывод:

n: 10, r: 5  
Value of nPr: 30240  
n: 3, r: 2  
Value of nPr: 6  
n: 1, r: 1  
Value of nPr: 1  
n: 8, r: 0  
Value of nPr: 1  
n: 4, r: 4  
Value of nPr: 24

C Программа для вычисления nPr

// C program to calculate the value of nPr  
#include   
  
// Function to calculate the factorial of a number  
int factorial(int num)  
{  
 if (num<=1)  
 {  
 return 1;  
 }  
 return num*factorial(num-1);  
}  
  
// Function to calculate the value of nPr  
int calculate_nPr(int n, int r)  
{  
 return factorial(n) / factorial(n - r);  
}  
  
  
int main()  
{  
 int n1 = 10;  
 int r1 = 5;  
 printf("n: %d, r: %d \n", n1, r1);  
 printf("Value of nPr: %d \n", calculate_nPr(n1, r1));  
  
 int n2 = 3;  
 int r2 = 2;  
 printf("n: %d, r: %d \n", n2, r2);  
 printf("Value of nPr: %d \n", calculate_nPr(n2, r2));  
  
 int n3 = 1;  
 int r3 = 1;  
 printf("n: %d, r: %d \n", n3, r3);  
 printf("Value of nPr: %d \n", calculate_nPr(n3, r3));  
  
 int n4 = 8;  
 int r4 = 0;  
 printf("n: %d, r: %d \n", n4, r4);  
 printf("Value of nPr: %d \n", calculate_nPr(n4, r4));  
  
 int n5 = 4;  
 int r5 = 4;  
 printf("n: %d, r: %d \n", n5, r5);  
 printf("Value of nPr: %d \n", calculate_nPr(n5, r5));  
  
return 0;  
}

Вывод:

n: 10, r: 5  
Value of nPr: 30240  
n: 3, r: 2  
Value of nPr: 6  
n: 1, r: 1  
Value of nPr: 1  
n: 8, r: 0  
Value of nPr: 1  
n: 4, r: 4  
Value of nPr: 24

Java Программа для вычисления nPr

// Java program to calculate the value of nPr  
public class Main  
{  
 // Function to calculate the factorial of a number  
 static int factorial(int num) {  
 if (num <= 1) {  
 return 1;  
 }  
 return num * factorial(num - 1);  
 }  
  
// Function to calculate the value of nPr  
 static int calculate_nPr(int n, int r) {  
 return factorial(n) / factorial(n - r);  
 }  
 public static void main(String[] args) {  
  
 int n1 = 10;  
 int r1 = 5;  
 System.out.println("n: " + n1 + ", r: " + r1);  
 System.out.println("Value of nPr: " + calculate_nPr(n1, r1));  
  
 int n2 = 3;  
 int r2 = 2;  
 System.out.println("n: " + n2 + ", r: " + r2);  
 System.out.println("Value of nPr: " + calculate_nPr(n2, r2));  
  
 int n3 = 1;  
 int r3 = 1;  
 System.out.println("n: " + n3 + ", r: " + r3);  
 System.out.println("Value of nPr: " + calculate_nPr(n3, r3));  
  
 int n4 = 8;  
 int r4 = 0;  
 System.out.println("n: " + n4 + ", r: " + r4);  
 System.out.println("Value of nPr: " + calculate_nPr(n4, r4));  
  
 int n5 = 4;  
 int r5 = 4;  
 System.out.println("n: " + n5 + ", r: " + r5);  
 System.out.println("Value of nPr: " + calculate_nPr(n5, r5));  
 }  
}

Вывод:

n: 10, r: 5  
Value of nPr: 30240  
n: 3, r: 2  
Value of nPr: 6  
n: 1, r: 1  
Value of nPr: 1  
n: 8, r: 0  
Value of nPr: 1  
n: 4, r: 4  
Value of nPr: 24

Когда подход с факториалом не годится (кратко)

  • Большие n приводят к переполнению стандартных типов (int, long).
  • Рекурсивный factorial может переполнить стек при больших n.
  • Если r > n или r < 0 — результат некорректен.
  • Для вещественных аргументов используйте функции гамма, но это уже другая задача.

Альтернативные подходы

  • Итеративное произведение: compute = 1; for i from 0 to r-1: compute *= (n - i). Это экономит память и время по сравнению с вычислением полных факториалов.
  • Использовать BigInteger / bigints для точности при больших значениях.
  • В статистике/комбинаторике иногда применяют логарифмы факториалов для работы с очень большими числами.

Практические рекомендации для разработчика и студента

Checklist (студент):

  • Пойми формулу nPr и реализуй её итеративно.
  • Обработай случаи r = 0, r > n, отрицательные r.
  • Пойми сложность O(r).

Checklist (разработчик):

  • Используй 64-bit или BigInteger, если n и r могут быть большими.
  • Предпочитай итеративный или стримовый метод для экономии операций.
  • Добавь тесты на граничные случаи.

Факты и оценки (факт-бокс)

  • Сложность по времени: O(r) при итеративном методе.
  • Сложность по памяти: O(1) (итеративно).
  • nPr = 1, если r = 0 или r = n = 0 по соглашению (в зависимости от контекста).
  • Переполнение — основной практический риск.

Принцип решения (SOP)

  1. Проверить входы: целые, 0 ≤ r ≤ n.
  2. Если r == 0 → вернуть 1.
  3. Итерировать i от 0 до r-1 и умножать результат на (n-i).
  4. Вернуть результат (используя подходящий тип данных).

Краткий глоссарий

  • nPr: число перестановок n по r — упорядоченные выборки без повторений.
  • Факториал (n!): произведение всех натуральных чис от 1 до n.

Решение наглядно: дерево решения (Mermaid)

flowchart TD
  A[Есть n и r?] --> B{r < 0 или r > n?}
  B -- Да --> C[Ошибка: некорректные входные данные]
  B -- Нет --> D{r == 0}
  D -- Да --> E[Вернуть 1]
  D -- Нет --> F[Вычислить произведение n*'n-1'*...*'n-r+1']
  F --> G[Вернуть результат]

Краткое резюме

  • nPr = n! / (n-r)! — базовая формула; на практике удобнее вычислять как произведение r множителей.
  • Для корректности и производительности избегайте вычисления полных факториалов и учитывайте переполнение.
  • Используйте bigint/BigInteger при больших n.

Связано: What Is a Fibonacci Sequence and How Do You Print One in Python, C++, and JavaScript?

Немного о том, как программирование влияет на мозг

Подобно творчеству, программирование влияет на мозг: улучшает способность к решению задач и структурированному мышлению. Это не прямая инструкция по вычислению nPr, но полезный побочный эффект изучения алгоритмов.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство