计算工具 · 数学计算

排列组合

P(n,k)/C(n,k)/阶乘大数

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 57 次使用
P(n,k) = n! / (n−k)!
公式代入逐步展开 · BigInt 精确连乘
杨辉三角(帕斯卡三角)第 n 行第 k 个 = C(n,k)
高亮 C(n,k) 所在格 · 点击任意格读取对应组合数 12
每行两端为 1,其余每个数等于上方两数之和;第 n 行第 k 个(均从 0 计)即 C(n,k)。
经典示例一键载入
概念速查排列 · 组合 · 阶乘 · 重复

排列 P(n,k)(有序选取,又记 Aₙᵏ):从 n 个不同元素中有序取出 k 个,P(n,k) = n! / (n−k)! = n·(n−1)···(n−k+1)。顺序不同视为不同方案。

组合 C(n,k)(无序选取,又记 Cₙᵏ 或 (ⁿₖ)):从 n 个不同元素中无序取出 k 个,C(n,k) = P(n,k) / k! = n! / (k!(n−k)!)。具有对称性 C(n,k) = C(n,n−k)。

阶乘 n!n! = n·(n−1)···2·1,规定 0! = 1。增长极快,20! 已达 19 位、达浮点 Number 安全整数上限之外——本工具一律 BigInt 精确计算。

重复排列 nᵏ:每次取出后放回,有序,共 nᵏ 种(如 k 位、每位 n 种取值的密码数)。

重复组合 C(n+k−1,k):可重复、无序地取 k 个,H(n,k) = C(n+k−1, k)(隔板法)。

杨辉三角:第 n 行(n 从 0 起)恰为 (a+b)ⁿ 的二项式系数 C(n,0)…C(n,n),每个数等于其上方相邻两数之和,故 C(n,k) = C(n−1,k−1) + C(n−1,k)。

就绪 · 全程 BigInt 任意精度,阶乘/排列/组合结果均为精确整数
第一节

关于本工具

About

当一道排列组合题从“选人”变成“考虑顺序”时,手算容易漏掉阶乘里的零。输入 n 和 k,工具直接输出 P(n,k)、C(n,k) 和对应的阶乘值,结果用大数表示,不丢位。数学竞赛复盘、概率作业验算、算法题手算前的快速确认——计算全部在浏览器内完成,数据不上传服务器。

使用场景

12人小组排值班表

12人的运维小组,每周一、三、五各需1人值班。按传统轮班,月底总有同事算错自己值了几次。用本工具算C(12,3)=220种可能的三人组合,再结合P(12,3)=1320种排序,能快速核对排班表是否覆盖了所有人、是否有某个人被排了三次。导出组合数后,直接在排班表里做减法,谁少值一目了然。

密码暴力测试选位

公司做渗透测试,需要评估6位纯数字密码(每位0-9)的穷举时间。但测试机只有2小时窗口,只能测部分组合。用C(10,6)=210种数字组合,再乘以P(6,6)=720种排列,得出理论总密码空间为1,000,000种。根据这个基数反推,2小时内可测完约14,400种,于是锁定前两位固定为'12',只测后四位,正好落在时间窗口内。

实验室试剂分组编号

生物实验室要测试5种抑制剂(A-E)对3种细胞系的抑制率,每种组合重复3次。总实验数为C(5,3)×3×3=90次(先选3种抑制剂,再算3种细胞系,重复3次)。用本工具算出C(5,3)=10种抑制剂组合,再搭配P(3,3)=6种细胞系排列顺序,能提前规划好96孔板的布局,避免重复加样或漏加。

保险精算组合定价

某款重疾险覆盖30种轻症,条款规定:确诊其中任意3种即可理赔。精算师需要计算所有可能的3种疾病组合数,以评估赔付概率。用C(30,3)=4060种组合,再结合每种疾病的发病率数据,能算出理论赔付率。工具直接输出4060这个数字,省去手动用阶乘公式计算的时间,直接代入定价模型。

棋牌赛抽签分组

32人参加围棋淘汰赛,需分8组,每组4人。用C(32,4)=35,960种可能的4人组合,再结合P(32,4)=863,040种排序,能快速验证抽签结果是否均匀——比如某组4人平均段位是否明显高于其他组。裁判现场用工具算出理论组合数,对比实际抽签结果,发现有一组3个业余5段+1个业余2段,组合概率仅为0.03%,判定抽签异常。

对比矩阵

维度本工具在线计算器传统方法
大数支持支持任意大整数(阶乘/组合数),无精度损失多数限 64 位整数,大数溢出或报错手工计算或依赖数学软件,大数易错
离线可用纯浏览器计算,无需网络需联网加载页面完全离线(纸笔/计算器)
隐私输入数据不出浏览器,无服务器上传输入可能传至后端处理完全本地,无数据泄露风险
速度即时返回结果(毫秒级)依赖网络延迟和服务端响应慢,尤其大数需分步计算
输入灵活性支持 n、k 分别输入,或仅 n 算阶乘通常只支持固定格式(如 C(n,k))需自行套公式,易出错
结果展示直接显示数值,无多余步骤可能附带广告或无关信息需自行核对计算过程
第二节

使用指南

Getting Started

使用步骤

  1. 1在「元素总数 n」和「选取个数 k」输入框中分别键入整数(n ≥ k ≥ 0),结果区自动显示 P(n,k)、C(n,k) 及 n! 三个数值
  2. 2点击结果区任意数值(如 C(10,3)=120),该数字即复制到剪贴板,页面出现短暂「已复制」提示
  3. 3若需阶乘结果,直接查看 n! 行:n ≤ 20 时显示精确整数,n > 20 时显示科学计数法(如 50! ≈ 3.0414e64)
  4. 4切换「排列」与「组合」标签可单独查看 P 或 C 的详细展开式(如 10×9×8 = 720),便于核对计算过程

输入输出示例

输入输出说明
P(10, 3)720常规:排列计算,验证 n=10, k=3 的基本乘法结果
C(10, 3)120常规:组合计算,与排列结果对比,验证组合数公式 C(n,k)=P(n,k)/k!
P(100, 0)1边界:k=0 时排列数为 1(空排列),验证工具正确处理零值
C(100, 100)1边界:k=n 时组合数为 1(全选),验证工具处理最大 k 值
C(1000, 500)270288240945436569515614693250...(大数,完整输出约 300 位)边界:大数组合,验证工具能否处理超大整数(阶乘大数场景)
P(5, 6)0(或错误提示:k 不能大于 n)易错:k>n 时排列无意义,验证工具是否给出明确错误提示而非返回错误值
C(5, -1)0(或错误提示:k 不能为负数)易错:负整数输入,验证工具是否对非法参数做校验
P(0, 0)1边界:n=0, k=0 时排列数为 1(空排列),验证工具对零阶乘的处理

常见错误对照

1.组合数 C(n,k) 中 k 大于 n

✗ 错误C(5,6)
✓ 修复C(5,5) 或 C(5,4)

组合数定义要求 0 ≤ k ≤ n,k 超过 n 时结果无意义(为 0),工具通常返回 0 或报错。

2.排列数 P(n,k) 中 k 大于 n

✗ 错误P(3,5)
✓ 修复P(5,3) 或 P(3,3)

排列数要求 k ≤ n,因为从 n 个元素中最多取 n 个排列;k > n 时不存在有效排列,工具返回 0。

3.阶乘输入非正整数(如小数或负数)

✗ 错误阶乘(3.5) 或 阶乘(-4)
✓ 修复阶乘(4) 或 阶乘(0)

阶乘仅定义于非负整数(0! = 1, n! = n×(n-1)!),小数和负数无定义,工具会拒绝计算。

4.混淆排列与组合的符号含义

✗ 错误计算从 5 人选 2 人当正副组长,用 C(5,2)
✓ 修复用 P(5,2)

排列考虑顺序(正副有别),组合不考虑。选组长时顺序重要,必须用排列 P(n,k) 而非组合 C(n,k)。

5.阶乘输入过大导致溢出或超时

✗ 错误计算 100000!
✓ 修复计算 100! 或 1000!(视工具精度)

阶乘增长极快(100! 约 9.3×10¹⁵⁷),浏览器或后端整数类型有上限,超大输入会返回 Infinity 或错误。

6.组合数 C(n,k) 中 k 为负数

✗ 错误C(10,-2)
✓ 修复C(10,2)

组合数定义要求 k ≥ 0,负 k 无组合意义,工具通常直接报错或返回 0。

7.排列数 P(n,k) 中 k=0 时误以为结果为 0

✗ 错误认为 P(5,0) = 0
✓ 修复P(5,0) = 1

排列数定义中 P(n,0)=1(空排列唯一),与组合数 C(n,0)=1 一致,不是 0。

8.混淆阶乘与双阶乘(!!)

✗ 错误计算 5!! 时输入阶乘(5) 得到 120
✓ 修复5!! = 5×3×1 = 15,需使用双阶乘工具或手动计算

双阶乘 n!! 是每隔一个数相乘,与阶乘 n! 完全不同;本工具只计算标准阶乘,输入 5!! 会被解析为 (5!)! 或报错。

第三节

工作原理

How It Works

核心公式

C(n, k) = n! / (k! × (n-k)!)

变量说明

  • n元素总数,正整数
  • k选取个数,0 ≤ k ≤ n
  • !阶乘,n! = 1×2×…×n

示例

从 10 个不同数字中选 3 个组成组合(不计顺序):C(10,3) = 10! / (3! × 7!) = (10×9×8) / (3×2×1) = 720 / 6 = 120 种。

输入 n、k校验合法性(n≥k≥0, 整数)阶乘计算(大数累乘)输出结果排列/组合选择(P 或 C 公式)公式代入(P=n!/(n-k)!)显示结果
用户输入 本地处理 输出结果
第四节

开发者集成

For Developers

5 种主流语言实现,复制即用:

import math # 排列数 P(n, k) = n! / (n-k)! def perm(n, k): if k > n or k < 0: return 0 return math.perm(n, k) # 组合数 C(n, k) = n! / (k! * (n-k)!) def comb(n, k): if k > n or k < 0: return 0 return math.comb(n, k) # 大数阶乘(Python 原生支持大整数) print(math.factorial(100)) # 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 print(perm(10, 3)) # 720 print(comb(10, 3)) # 120
// 大数阶乘(BigInt 支持任意大整数) function factorial(n) { if (n < 0) return 0n; let r = 1n; for (let i = 2n; i <= BigInt(n); i++) r *= i; return r; } // 排列数 P(n, k) function perm(n, k) { if (k > n || k < 0) return 0n; let r = 1n; for (let i = BigInt(n); i > BigInt(n - k); i--) r *= i; return r; } // 组合数 C(n, k) function comb(n, k) { if (k > n || k < 0) return 0n; if (k === 0 || k === n) return 1n; // 利用对称性减少计算 if (k > n - k) k = n - k; let r = 1n; for (let i = 1n; i <= BigInt(k); i++) { r = r * BigInt(n - Number(i) + 1) / i; } return r; } console.log(factorial(100).toString()); // 大数阶乘 console.log(perm(10, 3).toString()); // 720 console.log(comb(10, 3).toString()); // 120
package main import ( "fmt" "math/big" ) // 大数阶乘 func factorial(n int64) *big.Int { if n < 0 { return big.NewInt(0) } r := big.NewInt(1) for i := int64(2); i <= n; i++ { r.Mul(r, big.NewInt(i)) } return r } // 排列数 P(n, k) func perm(n, k int64) *big.Int { if k > n || k < 0 { return big.NewInt(0) } r := big.NewInt(1) for i := n; i > n-k; i-- { r.Mul(r, big.NewInt(i)) } return r } // 组合数 C(n, k) func comb(n, k int64) *big.Int { if k > n || k < 0 { return big.NewInt(0) } if k == 0 || k == n { return big.NewInt(1) } if k > n-k { k = n - k } r := big.NewInt(1) for i := int64(1); i <= k; i++ { r.Div(r.Mul(r, big.NewInt(n-i+1)), big.NewInt(i)) } return r } func main() { fmt.Println(factorial(100)) // 大数阶乘 fmt.Println(perm(10, 3)) // 720 fmt.Println(comb(10, 3)) // 120 }
use num_bigint::BigUint; use num_traits::One; // 大数阶乘 fn factorial(n: u64) -> BigUint { let mut r = BigUint::one(); for i in 2..=n { r *= i; } r } // 排列数 P(n, k) fn perm(n: u64, k: u64) -> BigUint { if k > n { return BigUint::ZERO; } let mut r = BigUint::one(); for i in (n - k + 1)..=n { r *= i; } r } // 组合数 C(n, k) fn comb(n: u64, k: u64) -> BigUint { if k > n { return BigUint::ZERO; } if k == 0 || k == n { return BigUint::one(); } let k = if k > n - k { n - k } else { k }; let mut r = BigUint::one(); for i in 1..=k { r = r * (n - i + 1) / i; } r } fn main() { println!("{}", factorial(100)); // 大数阶乘 println!("{}", perm(10, 3)); // 720 println!("{}", comb(10, 3)); // 120 }
import java.math.BigInteger; public class Combinatorics { // 大数阶乘 public static BigInteger factorial(int n) { if (n < 0) return BigInteger.ZERO; BigInteger r = BigInteger.ONE; for (int i = 2; i <= n; i++) { r = r.multiply(BigInteger.valueOf(i)); } return r; } // 排列数 P(n, k) public static BigInteger perm(int n, int k) { if (k > n || k < 0) return BigInteger.ZERO; BigInteger r = BigInteger.ONE; for (int i = n; i > n - k; i--) { r = r.multiply(BigInteger.valueOf(i)); } return r; } // 组合数 C(n, k) public static BigInteger comb(int n, int k) { if (k > n || k < 0) return BigInteger.ZERO; if (k == 0 || k == n) return BigInteger.ONE; if (k > n - k) k = n - k; BigInteger r = BigInteger.ONE; for (int i = 1; i <= k; i++) { r = r.multiply(BigInteger.valueOf(n - i + 1)).divide(BigInteger.valueOf(i)); } return r; } public static void main(String[] args) { System.out.println(factorial(100)); // 大数阶乘 System.out.println(perm(10, 3)); // 720 System.out.println(comb(10, 3)); // 120 } }
第五节

常见问题

Q & A
我算彩票组合,用 C(n,k) 还是 P(n,k)?

彩票开奖只看号码集合,不看顺序,所以用组合数 C(n,k)。例如双色球红球是 33 选 6,顺序无所谓,结果就是 C(33,6)=1,107,568 种。如果算排列(比如车牌号数字顺序不同算不同),才用 P(n,k)。本工具在输入区上方明确标注了“顺序无关用 C,顺序有关用 P”,选错模式结果会差很多倍。

n 和 k 最大能输多少?输 10000 会不会卡死?

本工具在浏览器本地计算,不依赖服务器。n 最大支持 10,000,k 最大支持 1,000。但注意:当 n 或 k 较大时(如 n=10,000, k=500),组合数结果位数极多(超过 1,000 位),浏览器渲染大数字会有短暂延迟,一般 1-3 秒内出结果。如果 n 和 k 都接近上限且 k 接近 n/2,计算量最大,建议等待几秒。如果输入超范围,输入框会直接提示。

算出来的结果有小数,是不是算错了?

组合数 C(n,k) 和排列数 P(n,k) 的结果一定是正整数,不会出现小数。如果看到小数,可能是输入了非整数(如 n=5.5),或把 n 和 k 填反了(如 k>n 时结果应为 0,但某些计算器会返回错误值)。本工具对输入做了校验:n 和 k 必须是非负整数且 k≤n,否则结果区会显示“参数无效”提示,不会给出小数结果。

阶乘算那么大,结果准不准?会不会溢出?

本工具使用 JavaScript 的 BigInt 类型计算,支持任意精度整数,不会像普通 Number 类型那样在 21! 就溢出。例如 100! 有 158 位,工具能精确输出每一位。但 BigInt 在输出时不会自动加科学计数法或千分位逗号,所以结果是一长串数字,建议直接复制使用。如果结果太长浏览器显示不全,可以全选复制到文本编辑器查看。

这个工具要联网吗?数据会不会上传?

完全不需要联网,所有计算都在你浏览器本地完成(FE 实现)。输入的数字和计算结果不会离开你的设备,也不会上传到任何服务器。关闭页面后数据自动清除。所以即使断网,只要页面之前加载过,也可以正常使用。适合处理敏感数据或离线场景。

我想算分组分配问题,比如 10 个人分成 3 组,每组人数不同,能用这个算吗?

本工具只算基本的排列数 P(n,k) 和组合数 C(n,k) 以及阶乘,不直接支持分组分配(多项式系数)。但你可以分步计算:例如 10 人分 3 组(3人、3人、4人),先算 C(10,3) 选第一组,再乘 C(7,3) 选第二组,最后 C(4,4) 固定第三组。结果 = C(10,3)×C(7,3)×C(4,4) = 120×35×1=4,200。注意如果组之间不区分顺序,还要除以组数相同的组数的阶乘。

为什么我按计算器算的 C(5,2) 是 10,这个工具也算 10,但书上公式是 10,没问题吧?

没问题,C(5,2)=10 是正确的。公式是 C(n,k)=n!/(k!(n-k)!),代入得 5!/(2!×3!)=120/(2×6)=10。可能你看到的“书”上写的是排列数 P(5,2)=20(即 5×4),混淆了排列和组合。本工具在结果区同时显示计算过程(分解式),你可以核对每一步是否和你手算一致。如果不放心,可以换小数字验算,如 C(4,2)=6。

结果太长看不懂,能不能显示成科学计数法?

目前结果直接输出精确整数,不提供科学计数法选项。但工具在结果下方附加了位数提示(如“共 158 位”),方便快速了解数量级。如果需要科学计数法,可以手动取前几位有效数字:例如 C(100,50)=100,891,344,545,564,193,334,812,497,256(共 29 位),近似为 1.0089×10^29。后续版本可能增加科学计数法切换,但精确值始终优先显示。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭