stl中partition演算法的解釋
Partition:分塊,將滿足條件的元素向前移動.(初始的相對位置將發生改變)
一個簡單的例子,把大於8的數分塊;
bool isok(int num) { return (num > 8); }
void main()
{ vector<int> v1; /*for (int i = 0; i <10; i++) { v1.push_back(i); }*/
v1.push_back(1); v1.push_back(3); v1.push_back(22); v1.push_back(10); v1.push_back(13); v1.push_back(8); v1.push_back(5); for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; partition(v1.begin(), v1.end(), isok);
for_each(v1.begin(), v1.end(), show<int>());
cin.get(); }
輸出結果:
1 3 22 10 13 8 5 13 10 22 3 1 8 5
不難發現 從22和3的位置 區分出來了,22之前大於8的 22之後小於8的,其實就是isok 為true 的向前移 為false的向後移,
Partition演算法的具體思路就是,先經過兩次內迴圈的查詢,前者使得結果為false,後者使得結果為true的元素已經找到,並交換彼此
這樣就實現了分塊,
過程演示:起始序列 1 3 22 10 13 8 5
經過兩次內迴圈查詢,先找到 1為false 、13為true ,將這兩個數交換 形成新的序列 13 3 22 10 1 8 5
繼續上步操作 找到 3為false 、10為true ,將這兩個數交換 形成新的序列 13 10 22 3 1 8 5
.......
最終得到13 10 22 3 1 8 5
Partition 實現的程式碼:
// TEMPLATE FUNCTION partition
template<class _BidIt,
class _Pr> inline
_BidIt _Partition(_BidIt _First, _BidIt _Last, _Pr _Pred)
{ // move elements satisfying _Pred to beginning of sequence
for (; ; ++_First)//最外層迴圈是一次往後面找元素
{ // find any out-of-order pair
for (; _First != _Last && _Pred(*_First); ++_First)//找到使得_Pred為false的元素
; // skip in-place elements at beginning
if (_First == _Last)
break; // done
for (; _First != --_Last && !_Pred(*_Last); )//找到是的_Pred為true的元素.
; // skip in-place elements at end
if (_First == _Last)
break; // done
_STD iter_swap(_First, _Last); // swap out-of-place pair and loop
//經過兩個內迴圈的查詢,前者是的_Pred為false,後者使得_Pred為true的元素已經找到,並交換彼此
}
return (_First);
}
需要注意的一點:vs2010的stl實現方式中,很喜歡使用if( -- iter )/for(_First != --_Last)這類的表示式,這類表示式的有點是程式碼量少,程式整潔,但是缺點就是容易造成語義判斷錯誤,比如--iter中,即使if判斷失敗iter也減一操作.
那有沒有不改變初始位置的呢,肯定有啦:
Stable_partition:將滿足條件的元素向前移動.(但不改變初始狀態的相對順序)
好了今天就先介紹到這兒吧。