1. 程式人生 > >stl中partition演算法的解釋

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:將滿足條件的元素向前移動.(但不改變初始狀態的相對順序)

好了今天就先介紹到這兒吧。