必须先排序,因为next_permutation从当前排列找字典序下一个,若未从最小排列开始则会遗漏前面所有排列;正确做法是先sort再循环调用。

next_permutation 是 C++ 标准库中生成字典序下一个排列的函数,它不“生成全排列”,而是“就地推进到下一个排列”——你得自己循环调用它,从初始升序开始,直到返回 false 为止。
为什么第一次调用前必须排序?
next_permutation 假设输入是当前排列,然后按字典序找“严格大于它的最小排列”。如果数组不是升序起始(比如 {3,1,2}),它只会从这个状态往后推,跳过前面所有更小的排列,结果不全。
- 正确做法:先用
sort(v.begin(), v.end())把容器排成最小字典序 - 错误写法:
vector<int> v = {2,1,3}; next_permutation(v.begin(), v.end());</int>→ 只得到{2,3,1},漏掉{1,2,3}、{1,3,2}等 - 注意:它只依赖元素的
比较,所以自定义类型要重载 <code>operator 或传比较器
怎么安全遍历全部排列?
标准写法是先排序,再用 do-while,因为第一个排列本身也要处理:
vector<int> v = {1,2,3};
sort(v.begin(), v.end());
do {
// 处理当前排列 v
for (int x : v) cout << x << ' ';
cout << '\n';
} while (next_permutation(v.begin(), v.end()));
- 别用
while (next_permutation(...))—— 会漏掉初始排列 - 返回值是
bool:成功推进返回true,到最大排列(降序)后返回false - 对重复元素也有效,但会跳过重复排列(例如
{1,1,2}只输出 3 种,不是 6 种)
常见报错和陷阱
编译或运行时出问题,大概率是迭代器或容器状态不对:
立即学习“C++免费学习笔记(深入)”;
-
std::next_permutation(v.begin(), v.end() + 1)→ 迭代器越界,v.end() + 1是非法地址 - 对
std::list直接用 → 编译失败,next_permutation要求随机访问迭代器(vector、array、原生数组可以,list不行) - 在循环里修改容器大小(如
push_back)→ 迭代器失效,后续next_permutation行为未定义 - 用
const vector→ 编译不过,它必须能修改元素
最常被忽略的一点:它改变的是原容器。如果你需要保留原始顺序,得先拷贝一份再操作;如果只是计数或校验,别在循环里反复 sort,那会打乱字典序推进逻辑。


















