天天看點

STL find_first_of查找算法

find_first_of() 算法可以在第一個序列中搜尋第二個序列在第一個序列中第一次出現的任何元序列被搜尋的範圍由輸入疊代器指定,但用于确定搜尋序列的疊代器至少是正向疊代器。用 == 運算符來比較這兩個序列中的元素,是以如果序列中是類類型的對象,這個類必須實作 operator==()。下面是一個使用 find_first_of() 的示例:

string text {"The world of searching"};
string vowels {"aeiou"};
auto iter = std::find_first_of (std::begin (text), std:: end (text), std::begin (vowels),std::end(vowels));
if(iter != std::end(text))
    std::cout << "We found '" << *iter << "'." << std::endl; //We found 'e'.
           

這段代碼會在 text 中查找第一次出現的 vowels 中的任意字元。在這個示例中,傳回的疊代器指向“The”的第三個字母。可以用循環來查找 text 中所有比對 vowels 中字元的字元:

為了展示我們可以這樣做,這裡使用了 for 循環。第一個循環控制表達式以 text 的開始疊代器為初值定義了 iter。第二個循環控制表達式調用 find_first_of(),在 [iter,std::end(text))  這段範圍内搜尋第一次出現的 vowel 中的字元。

find_first_of() 傳回的疊代器儲存在 iter 中,然後它被用來和 text 的結束疊代器進行比較。如果 iter 現在是 text 的結束疊代器,循環結束。如果 iter 不是 text 的結束疊代器,循環體會将這個字元附加到 iter 指向的 found 字元串上,然後自增 iter,使它指向下一個字元。這個字元會作為下一次搜尋的開始位置。這段代碼産生的輸出為:

string found {}; // Records characters that are found
for(auto iter = std::begin(text);(iter = std::find_first_of (iter,std::end (text),std::begin(vowels),std::end(vowels)))!= std::end(text);)
        found += *(iter++);
std::cout << "The characters \"" << found << "\" were found in text." << std::endl;
           

另一個版本的 find_first_of() 可以讓我們在第二個序列中搜尋指定範圍内的,可以使第 5 個參數指定的二進制謂詞傳回 true 的元素。這個序列中的元素不必是同種類型。當這個 == 運算符不支援所有這些元素的比較時,就可以用這個版本的算法來定義相等比較,但也可以用其他的方式來定義。例如:

std::vector<long> numbers{64L, 46L, -65L, -128L, 121L, 17L, 35L, 9L, 91L, 5L};
int factors[] {7, 11, 13};
auto iter = std::find_first_of(std::begin(numbers),std::end(numbers),std::begin(factors), std::end(factors),[](long v, long d) { return v % d == 0; });// Predicate - true for a match
if (iter != std::end (numbers))
    std::cout << *iter << " was found." << std::endl;
           

這個謂詞是一個 lambda 表達式,當第一個參數可以被第二個參數整除時,它傳回 true。

是以這段代碼會找到 -65,因為這是 numbers 中第一個可以被 factors 數組中的元素 13 整除的元素。斷言中的參數類型可以和序列元素的類型不同,隻要每個序列中的元素可以隐式轉換為參數所對應的類型。在這裡,factors 中的元素可以隐式轉換為 long 類型。

當然,可以用循環來查找所有使謂詞傳回 true 的元素:

std::vector<long> numbers {64L, 46L, -65L, -128L, 121L, 17L, 35L, 9L, 91L, 5L};
int factors[] {7, 11, 13};
std::vector<long> results;  // Stores elements found
auto iter = std::begin (numbers);
while ((iter = std:: find_first_of (iter, std::end (numbers),std::begin(factors), std::end(factors),[](long v, long d) { return v % d == 0; }))!= std::end(numbers))
    results.push_back(*iter++);
std::cout << results.size() <<" values were found:\n";
std::copy(std::begin(results), std::end(results),std::ostream_iterator < long > {std::cout," " });
std::cout << std::endl;
           

這段代碼可以找出 numbers 中所有以 factors 中的一個元素為因子的元素。while 循環會持續進行,隻要 find_first_of() 傳回的疊代器不是 numbers 的結束疊代器。iter 變量開始時指向 numbers 的第一個元素,然後會用它來儲存被找到元素的疊代器,先前的值被覆寫。在循環體中,iter 指向的元素會被儲存到 result 容器中,然後 iter 自增指向下一個元素。當循環結束時,results 包含的是找到的所有元素,然後用 copy() 算法輸出它們。