Как вычислить сочетания nCr (C(n, r)) — примеры на Python, C++, JavaScript, C и Java

Сочетание — математическая концепция, описывающая выбор нескольких объектов, в котором их порядок не важен. Базовая формула даёт число действительных сочетаний.
В этой статье вы научитесь вычислять nCr на Python, C++, JavaScript, C и Java. В каждом примере приведён пример вывода для нескольких значений.
Как вычислить nCr
Используйте следующую формулу сочетаний:
nCr = n! / (r! * (n-r)!)Где:
n = общее количество
C = сочетание
r = количество выбираемых элементов
! = факториалУсловие задачи
Даны значения n и r. Нужно вычислить nCr.
Пример 1: n = 10, r = 5 => nCr = 10! / (5! * 5!) = 252.
Пример 2: n = 8, r = 0 => nCr = 1.
C++ программа для вычисления nCr
Ниже — C++ программа, вычисляющая значение nCr (оригинальный код сохранён):
// C++ program to calculate the value of nCr
#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 nCr
int calculate_nCr(int n, int r)
{
return factorial(n) / (factorial(r) * factorial(n - r));
}
int main()
{
int n1 = 10;
int r1 = 5;
cout << "n: " << n1 << ", r: " << r1 << endl;
cout << "Value of nCr: " << calculate_nCr(n1, r1) << endl;
int n2 = 3;
int r2 = 2;
cout << "n: " << n2 << ", r: " << r2 << endl;
cout << "Value of nCr: " << calculate_nCr(n2, r2) << endl;
int n3 = 1;
int r3 = 1;
cout << "n: " << n3 << ", r: " << r3 << endl;
cout << "Value of nCr: " << calculate_nCr(n3, r3) << endl;
int n4 = 8;
int r4 = 0;
cout << "n: " << n4 << ", r: " << r4 << endl;
cout << "Value of nCr: " << calculate_nCr(n4, r4) << endl;
int n5 = 4;
int r5 = 4;
cout << "n: " << n5 << ", r: " << r5 << endl;
cout << "Value of nCr: " << calculate_nCr(n5, r5) << endl;
return 0;
} Вывод:
n: 10, r: 5
Value of nCr: 252
n: 3, r: 2
Value of nCr: 3
n: 1, r: 1
Value of nCr: 1
n: 8, r: 0
Value of nCr: 1
n: 4, r: 4
Value of nCr: 1Важно: рекурсивный факториал прост для понимания, но быстро приводит к переполнению и глубокой рекурсии при больших n. Ниже — альтернативы.
Python программа для вычисления nCr
Python-реализация (оригинальный код сохранён):
# Python program to calculate the value of nCr
# 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 nCr
def calculate_nCr(n, r):
return factorial(n) // (factorial(r) * factorial(n - r))
n1 = 10
r1 = 5
print("n:", n1, ",r:", r1)
print("Value of nCr:", calculate_nCr(n1, r1))
n2 = 3
r2 = 2
print("n:", n2, ",r:", r2)
print("Value of nCr:", calculate_nCr(n2, r2))
n3 = 1
r3 = 1
print("n:", n3, ",r:", r3)
print("Value of nCr:", calculate_nCr(n3, r3))
n4 = 8
r4 = 0
print("n:", n4, ",r:", r4)
print("Value of nCr:", calculate_nCr(n4, r4))
n5 = 4
r5 = 4
print("n:", n5, ",r:", r5)
print("Value of nCr:", calculate_nCr(n5, r5))Вывод (тот же, что и в примерах выше).
Совет: в Python 3.8+ есть встроенная функция math.comb(n, r), которая корректно обрабатывает большие n и эффективнее рекурсивного факториала.
JavaScript программа для вычисления nCr
JavaScript-реализация (оригинальный код сохранён):
// JavaScript program to calculate the value of nCr
// 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 nCr
function calculate_nCr(n, r) {
return factorial(n) / (factorial(r) * factorial(n - r));
}
var n1 = 10;
var r1 = 5;
document.write("n: " + n1 + ", r:" + r1 + " \n");
document.write("Value of nCr: " + calculate_nCr(n1, r1) + " \n");
var n2 = 3;
var r2 = 2;
document.write("n: " + n2 + ", r:" + r2 + " \n");
document.write("Value of nCr: " + calculate_nCr(n2, r2) + " \n");
var n3 = 1;
var r3 = 1;
document.write("n: " + n3 + ", r:" + r3 + " \n");
document.write("Value of nCr: " + calculate_nCr(n3, r3) + " \n");
var n4 = 8;
var r4 = 0;
document.write("n: " + n4 + ", r:" + r4 + " \n");
document.write("Value of nCr: " + calculate_nCr(n4, r4) + " \n");
var n5 = 4;
var r5 = 4;
document.write("n: " + n5 + ", r:" + r5 + " \n");
document.write("Value of nCr: " + calculate_nCr(n5, r5) + " \n");Вывод совпадает с примерами выше.
Примечание: для очень больших n используйте BigInt и итеративную формулу (см. раздел «Альтернативные подходы»).
C программа для вычисления nCr
C-реализация (оригинальный код сохранён):
// C program to calculate the value of nCr
#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 nCr
int calculate_nCr(int n, int r)
{
return factorial(n) / (factorial(r) * factorial(n - r));
}
int main()
{
int n1 = 10;
int r1 = 5;
printf("n: %d, r: %d \n", n1, r1);
printf("Value of nCr: %d \n", calculate_nCr(n1, r1));
int n2 = 3;
int r2 = 2;
printf("n: %d, r: %d \n", n2, r2);
printf("Value of nCr: %d \n", calculate_nCr(n2, r2));
int n3 = 1;
int r3 = 1;
printf("n: %d, r: %d \n", n3, r3);
printf("Value of nCr: %d \n", calculate_nCr(n3, r3));
int n4 = 8;
int r4 = 0;
printf("n: %d, r: %d \n", n4, r4);
printf("Value of nCr: %d \n", calculate_nCr(n4, r4));
int n5 = 4;
int r5 = 4;
printf("n: %d, r: %d \n", n5, r5);
printf("Value of nCr: %d \n", calculate_nCr(n5, r5));
return 0;
} Java программа для вычисления nCr
Java-реализация (оригинальный код сохранён):
// Java program to calculate the value of nCr
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 nCr
static int calculate_nCr(int n, int r) {
return factorial(n) / (factorial(r) * 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 nCr: " + calculate_nCr(n1, r1));
int n2 = 3;
int r2 = 2;
System.out.println("n: " + n2 + ", r: " + r2);
System.out.println("Value of nCr: " + calculate_nCr(n2, r2));
int n3 = 1;
int r3 = 1;
System.out.println("n: " + n3 + ", r: " + r3);
System.out.println("Value of nCr: " + calculate_nCr(n3, r3));
int n4 = 8;
int r4 = 0;
System.out.println("n: " + n4 + ", r: " + r4);
System.out.println("Value of nCr: " + calculate_nCr(n4, r4));
int n5 = 4;
int r5 = 4;
System.out.println("n: " + n5 + ", r: " + r5);
System.out.println("Value of nCr: " + calculate_nCr(n5, r5));
}
}Вывод для всех приведённых примеров одинаков: 252, 3, 1, 1, 1 соответственно.
Альтернативные подходы и когда их использовать
- Итеративная (мультипликативная) формула. Надёжнее, чем вычислять факториалы полностью:
result = 1
for i in 1..r:
result = result * (n - r + i) / iЭта схема минимизирует промежуточный рост чисел и уменьшает риск переполнения.
Паскалева треугольник (динамическое программирование): полезен, когда нужно вычислить множество nCr для разных r при фиксированном n.
Библиотеки больших чисел: Python math.comb (Python 3.8+), Java BigInteger (для больших значений), Boost.Multiprecision в C++, GMP для C, BigInt в JavaScript.
Числа с плавающей точкой (double): использовать осторожно — потеря точности для больших значений.
Ментальные модели и эвристики
- nCr симметрично: C(n, r) = C(n, n-r). Поэтому всегда выбирайте r = min(r, n-r) для оптимизации.
- Малые r: мультипликативная формула выполняется быстро и безопасно.
- Много запросов на небольшие n: предвычислите Паскалев треугольник.
Пограничные случаи и ошибки
- r < 0 или r > n — обычно nCr считается равным 0 (или это ошибка ввода).
- n или r нецелые — комбинации определяются для целых; для нецелых нужна другая теория.
- Переполнение при факториалах: факториал быстро выходит за пределы 32/64 бит.
Критерии приёмки
- Для тестов (n=10,r=5), (3,2), (1,1), (8,0), (4,4) программа должна выводить 252, 3, 1, 1, 1.
- Для n до 60 и 64-битных целых результат должен быть корректным при использовании unsigned long long (при аккуратной реализации).
- Для очень больших n использовать BigInteger/библиотеки произвольной точности и/или math.comb.
Быстрое руководство по выбору метода (практический чеклист)
- Нужны единичные вычисления, n <= 20: можно использовать рекурсивный факториал.
- n большое, но r маленькое: мультипликативная формула + уменьшение r до min(r, n-r).
- Много запросов для одного n: строить Паскалев треугольник.
- Очень большие значения: использовать библиотеки больших чисел (BigInteger, Boost.Multiprecision, GMP).
Пример потокового принятия решения (Mermaid)
flowchart TD
A[Нужно вычислить nCr?] --> B{r < 0 или r > n}
B -- Да --> C[Вернуть 0 или ошибку]
B -- Нет --> D{r == 0 или r == n}
D -- Да --> E[Вернуть 1]
D -- Нет --> F{n маленький и нет требований по точности}
F -- Да --> G[Рекурсивный факториал OK]
F -- Нет --> H{r маленькое}
H -- Да --> I[Мультипликативная формула]
H -- Нет --> J{Много запросов по одному n}
J -- Да --> K[Паскаль]
J -- Нет --> L[Использовать библиотеки больших чисел]Быстрые советы по языкам
- Python: используйте math.comb(n, r) (Python 3.8+) для корректности и производительности.
- Java: для больших значений используйте BigInteger и последовательный продукт с делением.
- C++: для больших значений применяйте boost::multiprecision::cpp_int или реализуйте мультипликативную формулу с проверкой переполнения.
- JavaScript: при больших значениях используйте BigInt и аккуратно делите, чтобы избежать дробной арифметики.
- C: используйте GMP или другие сторонние библиотеки для произвольной точности.
Краткое резюме
- Формула nCr = n! / (r! * (n-r)!) — корректна, но вычисление факториалов напрямую не всегда практично.
- Для надёжности используйте мультипликативную формулу, оптимизацию r -> min(r, n-r), или стандартные библиотеки (math.comb, BigInteger, Boost, GMP).
- Тесты и критерии приёмки помогают проверить корректность на граничных случаях.
Важно: выбирайте метод исходя из диапазона n, требований к производительности и наличия библиотек для больших чисел.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone