向量搜寻

问题描述

基本上,我的字符串向量vector<string> words中有很多单词。

我需要创建一个函数搜索整个向量中所有带有“ ly”的单词,并返回它们,例如(golly,helpfully,mostly,nearly)。

我如何使用std::find_if函数执行此操作,或者还有其他方法可以执行此操作?

我还需要在向量中找到比7个字母长的单词,我是否仍将std::find_if函数>=7结合使用?

解决方法

首先,在标准库中,std::copy_ifstd::find_if(根据您的要求)更合适。

第二,您需要根据不同的情况获得不同的单词列表。听起来好像有一个template function,它包装了std::copy_if,并提供了一种提供自定义比较(例如lambda function)功能的方法。

因此,我建议如下:

#include <algorithm> // std::copy_if
#include <iterator>  // std::cbegin,std::cend


template<typename Container,typename Predicate>
auto getElelmentsOf(const Container& container,const Predicate condition) /* noexcept */
{
    Container result;
    std::copy_if(std::cbegin(container),std::cend(container),std::back_inserter(result),condition);
    return result;
}

现在您可以编写类似的内容

// all the words with "ly"
const auto words_with_ly = [](const auto& ele) {
    return ele.find(std::string{ "ly" }) != std::string::npos;
};
const auto elemtsOfLy = getElelmentsOf(words,words_with_ly);  // function call


// find words that are longer than 7 letters
const auto words_with_size_7_more = [](const auto& ele) { return ele.size() > 7; };
const auto elemtsOfsize7More = getElelmentsOf(words,words_with_size_7_more);  // function call

See a Live Demo Online

,

您可以使用std::copy_if获取所有满足某些条件的元素。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // for std::copy_if
#include <iterator> // for std::back_inserter

using std::vector;
using std::string;

int main(void) {
    vector<string>words={
        "golly","hoge","lyric","helpfully","mostly","abcdefg","nearly","terrible"
    };
    vector<string> res_ly,res_7;

    // get all words that contains "ly"
    std::copy_if(words.begin(),words.end(),std::back_inserter(res_ly),[](const string& x){ return x.find("ly") != string::npos; });

    // get all words that are longer than 7 letters
    std::copy_if(words.begin(),std::back_inserter(res_7),[](const string& x){ return x.length() > 7; });

    // print what we got
    std::cout << "words with \"ly\":\n";
    for (const string& s : res_ly) std::cout << "  " << s << '\n';
    std::cout << "\nwords longer than 7 letters:\n";
    for (const string& s : res_7) std::cout << "  " << s << '\n';

    return 0;
}

输出:

words with "ly":
  golly
  lyric
  helpfully
  mostly
  nearly

words longer than 7 letters:
  helpfully
  terrible

如果您想使用std::find_if,则可以重复这样的搜索:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // for std::find_if
#include <iterator> // for std::next

using std::vector;
using std::string;

int main(void) {
    vector<string>words={
        "golly","terrible"
    };
    vector<string> res_ly;

    // get all words that contains "ly"
    for (vector<string>::iterator start = words.begin(); ;) {
        vector<string>::iterator next = std::find_if(start,[](const string& x){ return x.find("ly") != string::npos; });
        if (next == words.end()) {
            break;
        } else {
            res_ly.push_back(*next);
            start = std::next(next,1);
        }
    }

    // print what we got
    std::cout << "words with \"ly\":\n";
    for (const string& s : res_ly) std::cout << "  " << s << '\n';

    return 0;
}
,

我可以提出以下解决方案。

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>

std::vector<std::string> copy_strings( const std::vector<std::string> &v,const std::string &s )
{
    auto present = [&s]( const auto &item ) 
    {
        return item.find( s ) != std::string::npos; 
    };

    auto n = std::count_if( std::begin( v ),std::end( v ),present );
                            
    std::vector<std::string> result;
    result.reserve( n );
    
    std::copy_if( std::begin( v ),std::back_inserter( result ),present );
                  
    return result;                
}

int main() 
{
    std::vector<std::string> v =
    {
        "golly","nearly"
    };
    
    auto result = copy_strings( v,"ly" );
    
    for (const auto &item : result )
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';
    
    return 0;
}

程序输出为

golly helpfully mostly nearly