C++ 中的 std::next_permutation 和 prev_permutation

简介: 它用于将范围 [first, last) 中的元素重新排列为下一个字典序更大的排列。一个排列是 N! 元素可以采用的可能排列(其中 N 是范围内的元素数)。不同的排列可以根据它们在字典上相互比较的方式进行排序。代码的复杂度为 O(n*n!),其中还包括打印所有排列。

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战


std::next_permutation


它用于将范围 [first, last) 中的元素重新排列为下一个字典序更大的排列。一个排列是 N! 元素可以采用的可能排列(其中 N 是范围内的元素数)。不同的排列可以根据它们在

字典上相互比较的方式进行排序。代码的复杂度为 O(n*n!),其中还包括打印所有排列。


语法:


模板
bool next_permutation(首先是
双向
迭代器, 最后是 双向迭代器 ); 参数:
first, last : 初始的双向迭代器
和序列的最终位置。范围
used 是 [first, last),其中包含所有元素 
在 first 和 last 之间,包括指向的元素 
by first 但不是 last 指向的元素。
返回值:
true : 如果函数可以重新排列
对象作为字典序更大的排列。
否则,该函数返回 false 以指示 
安排不大于以前, 
但可能是最低的(按升序排序)。
复制代码


应用:  next_permutation 是为给定的值数组找到下一个字典序更大的值。


例子:

输入:1 2 3 的下一个排列是 
输出:1 3 2
输入:4 6 8 的下一个排列是 
输出:4 8 6
复制代码


#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
  int arr[] = { 1, 2, 3 };
  sort(arr, arr + 3);
  cout << "3!3个元素的可能排列:\n";
  do {
    cout << arr[0] << " " << arr[1] << " " << arr[2] << "\n";
  } while (next_permutation(arr, arr + 3));
  cout << "循环后: " << arr[0] << ' '
    << arr[1] << ' ' << arr[2] << '\n';
  return 0;
}
复制代码

输出:


3!3个元素的可能排列:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
循环后:1 2 3
复制代码


std::prev_permutation


它用于将范围 [first, last) 中的元素重新排列为前一个按字典顺序排列的排列。一个排列是 N! 元素可以采用的可能排列(其中 N 是范围内的元素数)。不同的排列可以根据它们在字典上相互比较的方式进行排序。


语法 :


模板
bool prev_permutation(首先是
双向
迭代器, 最后是 双向迭代器 ); 参数:
first, last : 初始的双向迭代器
和序列的最终位置。范围
使用的是 [first, last),其中包含所有
first 和 last 之间的元素,包括 
first 指向的元素但不是元素
最后指出。
返回值:
true : 如果函数可以重新排列
对象作为字典序较小的排列。
否则,该函数返回 false 以指示 
安排不低于以前, 
但最大的可能(按降序排序)。
复制代码


应用:  prev_permutation 是为给定的值数组找到以前的字典序较小的值。


例子:


输入:3 2 1的prev排列是 
输出:3 1 2 
输入:8 6 4 的上一个排列是 
输出:8 4 6
复制代码


#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
  int arr[] = { 1, 2, 3 };
  sort(arr, arr + 3);
  reverse(arr, arr + 3);
  cout << "3!3个元素的可能排列:\n";
  do {
    cout << arr[0] << " " << arr[1] << " " << arr[2] << "\n";
  } while (prev_permutation(arr, arr + 3));
  cout << "循环后: " << arr[0] << ' ' << arr[1]
    << ' ' << arr[2] << '\n';
  return 0;
}
复制代码


输出:


3!3个元素的可能排列:
3 2 1
3 1 2
2 3 1
2 1 3
1 3 2
1 2 3
循环后:3 2 1



目录
相关文章
|
5月前
|
存储 前端开发 安全
C++一分钟之-未来与承诺:std::future与std::promise
【6月更文挑战第27天】`std::future`和`std::promise`是C++异步编程的关键工具,用于处理未完成任务的结果。`future`代表异步任务的结果容器,可阻塞等待或检查结果是否就绪;`promise`用于设置`future`的值,允许多线程间通信。常见问题包括异常安全、多重获取、线程同步和未检查状态。解决办法涉及智能指针管理、明确获取时机、确保线程安全以及检查未来状态。示例展示了使用`std::async`和`future`执行异步任务并获取结果。
90 2
|
2月前
|
安全 C++
C++: std::once_flag 和 std::call_once
`std::once_flag` 和 `std::call_once` 是 C++11 引入的同步原语,确保某个函数在多线程环境中仅执行一次。
|
4月前
|
存储 C++ 运维
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
49 6
|
4月前
|
C++ 运维
开发与运维编译问题之在C++中在使用std::mutex后能自动释放锁如何解决
开发与运维编译问题之在C++中在使用std::mutex后能自动释放锁如何解决
65 2
|
5月前
|
安全 C++
C++一分钟之-字符串处理:std::string
【6月更文挑战第25天】`std::string`是C++文本处理的核心,存在于`&lt;string&gt;`库中。它支持初始化、访问、连接、查找、替换等操作。常见问题包括空指针解引用、越界访问和不当内存管理。要安全使用,确保字符串初始化,用`at()`检查边界,用`.empty()`检查空字符串,且无需手动释放内存。高效技巧包括预先分配内存、利用互转函数以及使用迭代器。记得正确比较和遍历字符串以保证代码效率和安全性。
69 5
|
5月前
|
存储 设计模式 安全
C++一分钟之-并发编程基础:线程与std::thread
【6月更文挑战第26天】C++11的`std::thread`简化了多线程编程,允许并发执行任务以提升效率。文中介绍了创建线程的基本方法,包括使用函数和lambda表达式,并强调了数据竞争、线程生命周期管理及异常安全等关键问题。通过示例展示了如何用互斥锁避免数据竞争,还提及了线程属性定制、线程局部存储和同步工具。理解并发编程的挑战与解决方案是提升程序性能的关键。
80 3
|
5月前
|
C++
c++中的using namespace std;
c++中的using namespace std;
146 1
|
6月前
|
存储 算法 C语言
从C语言到C++_39(C++笔试面试题)next_permutation刷力扣
从C语言到C++_39(C++笔试面试题)next_permutation刷力扣
59 5
|
5月前
|
C++
【C++航海王:追寻罗杰的编程之路】STL—next_permutation函数
【C++航海王:追寻罗杰的编程之路】STL—next_permutation函数
22 0
|
6月前
|
编译器 C语言 C++
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例