0

0

C++怎么求排列组合 C++中next_permutation用法【技巧】

穿越時空

穿越時空

发布时间:2026-03-03 13:18:01

|

615人浏览过

|

来源于php中文网

原创

next_permutation 返回 false 表示已无更大排列,自动重置为最小排列,并非报错;需先排序再用 do-while 枚举全部排列;求组合数应避免阶乘,改用递推公式 c(n,k)=c(n,k−1)×(n−k+1)/k 并利用对称性优化。

c++怎么求排列组合 c++中next_permutation用法【技巧】

next_permutation 为什么返回 false 却没报错

它不是报错函数,而是按字典序生成下一个排列后返回 true;如果当前已是最大排列(如降序数组),就重排为最小排列(升序)并返回 false。很多人误以为 false 表示出错或越界,其实只是“没下一个了”。

常见错误现象:next_permutation 调用一次就停,漏掉第一个排列(初始状态本身就是一个有效排列)。

  • 必须先对容器排序(升序),否则只能遍历从该初始状态出发的字典序子集
  • 想枚举全部排列,得先调用 sort,再用 do-while 包裹第一次调用
  • next_permutation 只接受随机访问迭代器,std::list 不行,std::vector 和原生数组可以
std::vector<int> v = {1, 2, 3};
std::sort(v.begin(), v.end()); // 必须有
do {
    // 处理 v 当前排列
} while (std::next_permutation(v.begin(), v.end()));

求组合数 C(n,k) 别直接算阶乘

阶乘爆炸快,intn > 13 就溢出,long long 也撑不过 n ≈ 20。而且组合数本身可能远小于中间阶乘结果,纯属白算。

正确做法是用递推公式:C(n,k) = C(n,k−1) × (n−k+1) / k,边乘边除,避免累积大数。

立即学习C++免费学习笔记(深入)”;

LibLib AI
LibLib AI

中国领先原创AI模型分享社区,拥有LibLib等于拥有了超多模型的模型库、免费的在线生图工具,不考虑配置的模型训练工具

下载
  • 顺序很重要:先乘后除,且每步都保证整除(数学上成立,但顺序错会截断小数)
  • k 超过 n/2 时,用 C(n,k) = C(n,n−k) 减少循环次数
  • 若只需模意义下结果(比如 1e9+7),除法要转成乘逆元,不能直接用 /
long long comb(int n, int k) {
    if (k > n || k < 0) return 0;
    k = std::min(k, n - k);
    long long res = 1;
    for (int i = 1; i <= k; ++i) {
        res = res * (n - k + i) / i; // 整除安全
    }
    return res;
}

next_permutation 对重复元素怎么处理

它按字典序跳过重复排列,结果中不会出现两个完全相同的排列——前提是输入已排序。例如 {1,1,2} 排序后调用,只会生成 3 个不同排列:{1,1,2}{1,2,1}{2,1,1}

但如果你传入未排序的重复数组(如 {1,2,1}),next_permutation 仍会工作,只是起点不标准,容易漏或重。

  • 重复元素下,next_permutation 的行为是定义良好的,但“全部枚举”必须以升序为起点
  • 不需要额外去重逻辑,库函数内部已处理
  • 若需所有子集的排列(比如从 5 个数里选 3 个再排列),得嵌套:先用 std::combinations(没有!)手动选,再对每个子集调用 next_permutation

性能和替代方案:什么情况不该用 next_permutation

它时间复杂度是 O(n),单次调用很快,但枚举全部排列是 O(n! × n),n=10 就要千万级操作,n=12 直接卡住。实际项目中,多数需求其实只需要部分排列、带剪枝的搜索,或根本不需要显式列出。

  • 做回溯题(如 N 皇后、数独)时,手写递归 + 剪枝比生成全排列再验证快得多
  • 需要第 k 个字典序排列?用康托展开,O(n²) 定位,不用枚举前面 k−1 个
  • 编译器优化对 next_permutation 有限,大量调用时注意别让它在 hot path 上

真正要用它的时候,往往是你明确知道 n ≤ 8,或者只跑测试用例——生产代码里硬写全排列枚举,基本等于提前埋雷。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

406

2023.09.04

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

104

2023.09.25

python如何计算数的阶乘
python如何计算数的阶乘

方法:1、使用循环;2、使用递归;3、使用math模块;4、使用reduce函数。更多详细python如何计算数的阶乘的内容,可以阅读下面的文章。

177

2023.11.13

python求阶乘教程大全
python求阶乘教程大全

本专题整合了python求阶乘相关教程,阅读专题下面的文章了解更多详细内容。

13

2025.11.08

python语言求阶乘
python语言求阶乘

本专题整合了python中阶乘相关教程,阅读专题下面的文章了解更多详细步骤。

43

2025.12.06

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

910

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

598

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

0

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 10.6万人学习

C 教程
C 教程

共75课时 | 5.1万人学习

C++教程
C++教程

共115课时 | 20.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号