1. 程式人生 > >STL partition_point分割演算法

STL partition_point分割演算法

可以用 partition_point() 演算法來獲取分割槽序列中第一個分割槽的結束迭代器,它的前兩個引數定義檢查範圍的正向迭代器,最後一個引數是用來對序列進行分割槽的謂詞。我們通常不知道每個分割槽中元素的個數,這個演算法使我們能夠訪問和提取這些分割槽中的元素。例如:

std::vector<double> temperatures {65, 75, 56, 48, 31, 28, 32, 29, 40, 41, 44, 50};
auto average = std::accumulate(std::begin(temperatures),std::end(temperatures), 0.0)/ temperatures.size();
auto predicate = [average](double t) { return t < average; };
std::stable_partition(std::begin(temperatures), std::end(temperatures), predicate);
auto iter = std::partition_point(std::begin(temperatures),std::end(temperatures), predicate);
std::cout << "Elements in the first partition: ";
std::copy(std::begin(temperatures), iter,std::ostream_iterator<double>{std::cout, " "});
std::cout << "\nElements in the second partition: ";std::copy(iter, std::end(temperatures),std::ostream_iterator<double>{std::cout, " "});
std::cout << std::endl;

這段程式碼會相對於平均溫度對 temperatures 中的元素進行分割槽,並通過呼叫 partition_point() 找到這個序列的分割槽點。這個分割槽點是第一個分割槽的結束迭代器,它被儲存在 iter 中。所以 [std::begin(temperatures),iter) 對應的就是第一個分割槽中的元素,[iter,std::end(temperatures)) 包含的是第二個分割槽中的元素。這裡使用兩次 copy() 演算法來輸出分割槽,輸出內容如下:

Elements in the first partition: 31 28 32 29 40 41 44
Elements in the second partition: 65 75 56 48 50

在使用 partition_point() 之前,需要確定序列是否已經被分割槽。如果對此不是很確定,在這種情況下可以使用 is_partitioned() 來判斷。它的引數是用來指定序列的輸入迭代器和用來對序列進行分割槽的謂詞。如果這個序列已經被分割槽,這個演算法就返回 true,否則返回 false。

在對 temperatures 使用 partition_point() 演算法之前,可以先用它來驗證這個序列:

if(std::is_partitioned(std::begin(temperatures), std::end(temperatures),[average](double t) { return t < average; }))
{
    auto iter = std::partition_point(std::begin(temperatures),std::end(temperatures), [average](double t) { return t < average; });
    std::cout << "Elements in the first partition: ";
    std::copy(std::begin(temperatures), iter,std::ostream_iterator<double>{std::cout, " " });
    std::cout << "\nElements in the second partition: ";
    std::copy(iter, std::end(temperatures),std::ostream_iterator<double>{std::cout," "});
    std::cout << std::endl;
}
else
    std::cout << "Range is not partitioned." << std::endl;

只有在 is_partitioned() 返回 true 時,這段程式碼才會執行。如果 if 語句為 true,iter 變數會指向分割槽點。如果想在後面繼續使用 iter,可以按如下方式在 if 語句之前定義它:

std::vector<double>::iterator iter;

在所有容器型別的模板中都定義了這樣的迭代器類型別名,它們使迭代器變得可以使用。它對應於這個容器型別的成員函式 begin() 和 end() 所返回的迭代器型別。