1. 程式人生 > >STL find_end查詢演算法

STL find_end查詢演算法

find_end() 會在一個序列中查詢最後一個和另一個元素段匹配的匹配項,也可以看作在一個元素序列中查詢子序列的最後一個匹配項。這個演算法會返回一個指向子序列的最後一個匹配項的第一個元素的迭代器,或是一個指向這個序列的結束迭代器。下面是一個示例:

string text {"Smith, where Jones had had \"had\", had had \"had had\"." " \"Had had\" had had the examiners\' approval."};
std::cout << text << std::endl;
string phrase {"had had"};
auto iter = std::find_end(std::begin(text), std::end(text), std::begin (phrase),std::end(phrase));
if(iter != std::end(text))
std::cout << "The last \"" << phrase<< "\" was found at index "<< std::distance (std::begin (text), iter) << std::endl;

這段程式碼會從 text 中搜索“had had”的最後一個匹配項,並輸出如下內容:

Smith, where Jones had had "had", had had "had had" . "Had had" had had the examiners' approval.
The last "had had" was found at index 63

可以在 text 中搜索 phrase 的所有匹配項。在這個示例中只會記錄匹配項的個數:

size_t count {};
auto iter = std::end(text);
auto end_iter = iter;
while((iter = std::find_end(std::begin(text), end_iter, std::begin(phrase), std::end(phrase))) != end_iter)
{
    ++count;
    end_iter = iter;
}
std::cout << "\n\""<< phrase << "\" was found " << count <<" times." << std::endl;

這個 while 迴圈表示式會進行這項搜尋工作。迴圈表示式會在 [std::begin(text),end_iter) 這個範圍內搜尋 phrase。最開始的搜尋範圍包含 text 中的全部元素。為了說明這裡發生了什麼,下面用圖 1 來演示這個過程。

圖1 用find_end()反覆搜尋

find_end() 返回的迭代器被儲存在 iter 中,當它等於 end_iter,即 iter 先前的值時,迴圈結束。因為 find_end() 會查詢子序列的最後一個匹配項,下一個搜尋範圍的結束迭代器 end_iter 會變為這個演算法所返回的迭代器。這個迭代器會指向被找到序列的第一個字元,所以下一次搜尋會從 text 的這個點開始,忽略已找到的元素。迴圈體中 count 自增後,end_iter 被設為 iter。這麼做是必要的,因為如果下一次搜尋找到 phrase,就會返回這個迭代器。

另一個版本的 find_end() 接受一個用來比較元素的二元謂詞作為第 5 個引數,可以用它來重複前面的搜尋並忽“大小寫:

size_t count {};
auto iter = std::end(text);
auto end_iter = iter;
while((iter = std::find_end(std::begin(text), end_iter, std::begin(phrase), std::end (phrase) , [] (char ch1, char ch2) { return std::toupper (ch1) == std::toupper(ch2);})) != end_iter)
{
    ++count;
    end_iter = iter;
}

在將字元轉換為大寫後,會按對比較這兩個序列中的元素。在 text 中會找到 phrase 的 5 個例項,因為找到的"Had had"也和 phrase 相等。