C++ 標準庫 permutation
首先,permutation指的是對元素的重排,比如a , b , c 三個元素的所有的重排為 abc, acb, bac,bca,cab,cba 總共 3! = 6 中情況,但是如何聲稱這六種情況呢,C++標準庫定義了函式 next_permutation,來生成一組元素的所有的全排列。首先,瞭解該函式的宣告以及實現:
函式宣告為: [摘自 www.cplusplus.com]
std::next_permutation
此兩者在C++的標準庫中被實現為模板的形式。
default (1) template <class BidirectionalIterator> bool next_permutation (BidirectionalIterator first, BidirectionalIterator last);custom (2) template <class BidirectionalIterator, class Compare> bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp);引數說明:
first last 其中的迭代器 first 和 last 用來表示元素的範圍 [ first, last ) 不對稱邊界。
再來就是該迭代器的型別為雙向迭代器,那麼也就是說 隨機迭代器和雙向迭代器可以作為該函式的引數傳入。
Compare comp 是用來比較的函式,也就是說用來決定生成的重排的順序函式,預設使用的是opeartor<符號,當然你自己也可以定義自己的比較函式,作為函式指標傳入,或者是定義仿函式,傳入函式物件,
返回值:
如果在該comp函式下,下一個重拍序列存在,則返回true,走則返回false,也就是說這一次的重拍序列已經是最後一個重排序列了。
比如,如果採用的是operator<作為比較函式的話,那麼 {1,2,3}的最後一個重排就是321,第一個重排就是123,在321之後再呼叫next_premutation,返回false,但是該函式會將原來的陣列排列為 1,2,3。
副作用:
該函式會修改傳入的元素順序。
執行結果為:#include #include int main() { int A[] = {1,3,2}; do{ std::cout << A[0] << " " << A[1] << " " << A[2] << std::endl; }while(std::next_permutation(A,A+3)); return 0; }
可以看出,該函式會自動在當前的元素的順序基礎上,生成後續的排列。也就是說,如果要生成所有的permutation的話,那麼需要先將元素排序。
OK!!用法已經詳解了,接下來便是要將該函式的真面目示人了。
template <class _BidirectionalIter>
bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
__STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
__STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,
_LessThanComparable);
if (__first == __last) //如果傳入引數為空的話,
return false;
_BidirectionalIter __i = __first;
++__i;
if (__i == __last) //如果只有一個元素
return false;
__i = __last;
--__i;
for(;;) {
_BidirectionalIter __ii = __i;
--__i;
if (*__i < *__ii) {
_BidirectionalIter __j = __last;
while (!(*__i < *--__j))
{}
iter_swap(__i, __j);
reverse(__ii, __last);
return true;
}
if (__i == __first) {
reverse(__first, __last);
return false;
}
}
}
以上為STL中的版本,該函式實現原理如下:
在當前的序列中,從尾端出發往前找到一對相鄰的元素 a[ i ] 與 a[ j ] ,使得 a[ i ] < a[ j ], (此處預設採用less函式物件),然後再從尾端出發找到一個字元 a[ k ] ,使得 a[ i ] < a[ k ], 此時交換 a[ k ] 與 a[ i ], 並且將a[ j --- end) 之間的所有元素逆序即可。程式碼實現為:
template<class bidirectional_iterator>
bool permutation(bidirectional_iterator first, bidirectional_iterator last)
{
if(first == last) return false; //如果沒有元素
if(first + 1 == last) return false; //如果只有一個元素
bidirectional_iterator j = last;
--j;
while(1)
{
bidirectional_iterator i = j;
--i;
//find a[i] < a[j] and they are adjacent
if(*i < *j)
{
bidirectional_iterator k = last;
while(!(*i < *--k)){}
std::iter_swap(i,k); //或者是 swap(*i, *k);
std::reverse(j,last);
return true;
}
--j;
//no such a[i] < a[i+1] pair found
if( j == first)
{
//restore the first of the permutation
std::reverse(first, last);
return false;
}
}
}
上述程式碼中的swap函式必須是iter_swap函式,利用swap只是交換了迭代器的指標,並未實際改變元素的位。也可以使用swap(*i, *k);
關於該函式的comp物件的實際形式,接著會有一篇關於函式指標以及函式物件的博文,詳細講解。
2014 5.18 更新版本
看到網上的一篇文章的求解全排列:
如果只需要直接返回所有的全排列的話,那麼很簡單,依次交換字串中的相鄰的字元即可。
如下圖:
相關推薦
C++ 標準庫 permutation
首先,permutation指的是對元素的重排,比如a , b , c 三個元素的所有的重排為 abc, acb, bac,bca,cab,cba 總共 3! = 6 中情況,但是如何聲稱這六種情況呢,C++標準庫定義了函式 next_permutation,來
C標準庫pow函數精度問題。
一般來說 nbsp any pre 4.5 logs urn padding signed #include <stdio.h> int main () { int temp,i; double a=2.4568; unsigned char b[5]
C標準庫stdlib.h概況
庫函數 字符常量 函數返回 表示 size_t 字節 max size 字符集 庫變量 size_t 這是無符號整數類型,它是 sizeof 關鍵字的結果 wchar_t 這是一個寬字符常量大小的整數類型。 div_t 這是 div 函數返回的結構 ldiv_t 這
C++標準庫算法
fill acc bsp c++ count nbsp size count() style 一、只讀算法 1. find() 2. count() 3. accumulate 4. equal 二、寫入算法 1. fill 2. fill_nC++標準庫算法
C++標準庫
補充 ref idt 例如 cat bool 操縱程序 nta 取余 C++標準庫 C++標準庫和標準模版庫在線資料查詢網址: http://en.cppreference.com/w/ 或者 http://www.cplusplus.com/ C+
C 標準庫 - string.h之strncpy使用
填充 reat 函數 clas != count imu serve uno strncpy 把 src 所指向的字符串復制到 dest,最多復制 n 個字符。當 src 的長度小於 n 時,dest 的剩余部分將用空字節填充。 char *strncpy(char
C 標準庫 - string.h之strcat使用
www. href 產生 rmi put for turned med main strcat Appends a copy of the source string to the destination string. The terminating null cha
C 標準庫 - string.h之strlen使用
rac ati oob [] mine eat including 定義 mina strlen Returns the length of the C string str. The length of a C string is determined by the
C 標準庫 - string.h之memcpy使用
uno over character copies www. zhang 別名 .com val memcpy Copy block of memory Copies the values of num bytes from the location pointed t
C 標準庫IO緩沖區和內核緩沖區的區別
io緩沖區 lose 信息 同一文件 upload 同步 load IT 覆蓋 1.C標準庫的I/O緩沖區 UNIX的傳統 是Everything is a file,鍵盤、顯示器、串口、磁盤等設備在/dev 目錄下都有一個特殊的設備文件與之對應,這些設
c++標準庫裏的sort()排序函數
C++ STL Sort()函數是c++一種排序方法之一,學會了這種方法也打消我學習c++以來使用的冒泡排序和選擇排序所帶來的執行效率不高的問題!因為它使用的排序方法是類似於快排的方法,時間復雜度為n*log2(n),執行效率較高!一,sort()排序函數的使用方法I)Sort函數包含在頭文件為#in
C++標準庫vector類型的使用和操作總結
種類 style 開始 spa log string string類 gpo targe vector是一種類型對象的集合,它是一種順序容器,容器中的所有對象必須都是同一種類型。vector的對象是可以動態生長的,這說明它在初始化時可以不用指定大小,而是再使用時根據元素
c++標準庫函數棧和隊列
regex nbsp 頭文件 word pretty tac reg 包含 AS 使用標準庫的棧和隊列時, 應包含先關頭文件. 在棧中應包含頭文件: #include< stack > 定義: stack< int > s; s.empty();
什麽是 C 和 C ++ 標準庫?
lec 內存占用 串處理 函數 背景 成員 流程 出版 contain 簡要介紹編寫C/C ++應用程序的領域,標準庫的作用以及它是如何在各種操作系統中實現的。我已經接觸C++一段時間了,一開始就讓我感到疑惑的是其內部結構:我所使用的內核函數和類從何而來? 誰發明了它們?
初探 C++ 標準庫(二十六)
C++ 標準庫 cout cin 操作符重載 今天我們來看下 C++ 中的標準庫,這幾天我們一直學習的是 C++ 中的一大難點,操作符重載。那麽我們想想操作符左移 << 可以重載嗎?操作符 << 的原生語義是按位左移,如:1 << 2,則
C++標準庫(三)之STL算法
out section 區間 and include pla sort 不同 重復元素 算法頭文件: #include<algorithm> #include<numeric> 算法簡介:STL算法采用覆蓋模式而非安插模式,所以調用者必須保證有足夠
C++標準庫(四)之String
條件 val first operator ins iter substr() oid tof String 常見操作 bool empty() const size_type size() const size_type length() const size_type
C++標準庫(六)之traits技術
對象的引用 pointer 處的 fde ifd partial clas .... n) traits技術 原理:利用template的參數推導機制獲取傳入的參數型別。 template<typename T> struct Iter { typede
C++標準庫(七)之iterator
控制 ins opera access 指向 begin 任務 multiset fse iterator iterator模式:提供一種方法,使之能依次訪問容器內的各個元素,而又不暴露該聚合物內部的表述方式。 STL的中心思想是將算法與數據結構分離,彼此獨立設計,最後在用
C++標準庫——STL之空間配置器
但是 chunk 內容 既然 部分 如何 標識 stl源碼 strong 聲明:源碼同《STL源碼剖析》(侯捷) STL: C++標準的模板庫,通用性高。 常見的數據結構封裝。 提供常用的通用算法。 STL六大組件: 容器 算法 叠