找到/使用基于其元素的向量

时间:2011-12-03 12:57:17

标签: c++ vector

VC ++ 2010

假设我有以下内容:

struct person {
    char *  name;
    int     age;
};

然后我有一个包含这些的载体:

std::vector <person> person_list;

现在,在推回其中一些元素后,如何根据其中一个属性找到一个元素?最好的情况,我希望它返回一个指向矢量元素'where name = string'交易类型的指针。

3 个答案:

答案 0 :(得分:2)

(请使用std::string代替char*,以避免泄漏或悬挂指针。)

您可以使用std::find_if来获取该元素的迭代器:

#include <algorithm>   // allow us to use  std::find_if

struct NameFinder
{
    std::string target;
    bool operator()(const person& pers) const
    {
        return pers.name == target;
    }
};

...

NameFinder finder;
finder.target = "whatever name you want";

std::vector<person>::iterator it = 
                std::find_if(person_list.begin(), person_list.end(), finder);

std::cout << "name = " << it->name << "; age = " << it->age << std::endl;

这里的NameFinder是一个函数对象,它检查一个人的名字是否与给定目标匹配。

答案 1 :(得分:1)

改善的一个建议。使用std::string代替char*。你必须#include <string>

  • 在C ++ 11中,您可以使用lamda和std::find_if作为:

    #include <algorithm>
    
    auto it = std::find_if(persons.begin(), persons.end(), [](const person & p)
                                {
                                     return p.name = "string"; 
                                });
    
  • 在C ++ 03中,您可以使用functor作为谓词:

    #include <algorithm>
    
    struct name_predicate
    {
        std::string name;
        name_predicate(std::string const & name) : name(name) {}
        bool operator()(person const & p) { return name == p.name; }
    };
    
    std::vector<person>::iterator it = std::find_if(persons.begin(), 
                                                    persons.end(),
                                                    name_predicate("string"));
    

答案 2 :(得分:1)

stdlib使用迭代器而不是指针。在algorithm标题中,您会找到功能模板findfind_if。第一个按值标识搜索元素,第二个按谓词搜索,并返回iterator到第一个匹配。您可以将operator==的重载添加到您的person类,并使用第一个版本或编写谓词,然后使用第二个版本。

这是一个示例谓词:

struct person_equal {
  bool operator()(const person& p, const char* name) {
    return strcmp(p.name, name);
  }
};

请注意,它使用C函数strcmp。您应该将std::stringS存储在person个对象中,而不是char*

现在,这个谓词有两个元素,但find_if需要一元谓词。您需要将bind第二个参数设置为某个固定值。在这里,我使用已弃用的bind2nd。您应该使用boost:::bind或C ++ TR1替换。

std::find_if(vec.begin(), vec.end(), std::bind2nd(person_equal(), "foobar"));

在C ++ 0x中,您将使用lambda:

std::find_if(v.begin(), v.end(), [](const person& p) { return strcmp(p.name, "foobar"); });

或者你可以迭代:

std::vector<person>::iterator my_find(std::vector<person>& v) {
  for(std::vector<person>::iterator it = v.begin(), it != v.end(), ++it) {
    if(strcmp(it->name, "foobar")) return it;
  }
}