函数实现原理如下:
在当前序列中,从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
template<typename _BidirectionalIterator> bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { if (__first == __last) //空区间 return false; _BidirectionalIterator __i = __first; ++__i; if (__i == __last) //只有一个元素 return false; __i = __last; //指向尾端 --__i; for(;;) { _BidirectionalIterator __ii = __i; --__i; //以上,锁定一组(两个)相邻元素 if (*__i < *__ii) { //如果前一个元素小于后一个元素 _BidirectionalIterator __j = __last; //令__j指向尾端 while (!(*__i < *--__j)) //由尾端往前找,直到遇到比*__i大的元素 { } std::iter_swap(__i, __j); //交换__i,__j std::reverse(__ii, __last); //将 __ii 之后的元素全部逆向重排 return true; } if (__i == __first) //进行到最前面了 { std::reverse(__first, __last); //全部逆向重排 return false; } } }
template<typename _BidirectionalIterator> bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { if (__first == __last) return false; _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIterator __ii = __i; --__i; if (*__ii < *__i) { _BidirectionalIterator __j = __last; while (!(*--__j < *__i)) { } std::iter_swap(__i, __j); std::reverse(__ii, __last); return true; } if (__i == __first) { std::reverse(__first, __last); return false; } } }
#include <cstdio> #include <algorithm> #include <string> #include <iostream> using namespace std; int main() { int a[10],b[10]; int n; puts("输入数字个数:"); scanf("%d",&n); for(int i = 0; i < n; i++) { scanf("%d",&a[i]); b[i] = a[i]; } // sort(a,a+n); puts("prev_permutation:"); while(prev_permutation(b,b+n)) { for(int i = 0; i < n; i++) { printf("%d ",b[i]); } printf("\n"); } puts("next_premutation:"); while(next_permutation(a,a+n)) { for(int i = 0; i < n; i++) { printf("%d ",a[i]); } printf("\n"); } }string:
#include <iostream> #include <algorithm> #include <string> using namespace std; int main() { string str; cin >> str; sort(str.begin(), str.end()); cout << str << endl; while (next_permutation(str.begin(), str.end())) { cout << str << endl; } return 0; }
bool
. The value returned indicates whether the first argument is considered to go before the second in the specific
strict weak ordering it defines.
This can either be a function pointer or a function object.
重排列之后的序列为最小字典列(对于prev反之);
|
|
The 3! possible permutations with 3 elements: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 After loop: 1 2 3 |