【问题标题】:C++ To filter a class vector using algorithmC ++使用算法过滤类向量
【发布时间】:2012-02-12 09:49:29
【问题描述】:

如何使用算法按国家/地区过滤类向量 studentList?这意味着我只显示来自“美国”国家的学生的详细信息。

bool checkCountry (string x, string y) 
{
  return (x == y);
}
vector<Student> studentList;
studentList.push_back(Student("Tom", 'M', "91213242", "America"));
studentList.push_back(Student("Jessilyn", 'F', "98422333", "Europe"));

【问题讨论】:

  • 你需要erase-remove idiom
  • @Oli - 仅当他想删除非美国条目时。我认为他的意思是他想保留矢量,但只显示某些元素。
  • 我必须保留其他条目,所以擦除删除不起作用?

标签: c++ algorithm class vector filter


【解决方案1】:
using std::copy_if;
using std::ostream_iterator;
using std::cout;

enum Region {
    AMERICA,
    EUROPE,
    REST_OF_WORLD
};

bool is_american(const Student& student)
{
    return student.isFrom(AMERICA);
}

copy_if(students.begin(), students.end(),
        ostream_iterator<Student>(cout, "\n"),
        is_american);

在 C++11 中使用 lambda,并允许选择区域:

void show_students_from_region(const Region& region)
{
    copy_if(students.begin(), students.end(),
            ostream_iterator<Student>(cout, "\n"),
            [&](const Student& student) { return student.isFrom(region); });
}

【讨论】:

  • 如果我的菜单必须允许用户选择他/她希望过滤掉的国家怎么办?
【解决方案2】:

您可以使用 boost 中的filter_iteratorHere is an example 底层集合是一个普通数组。

以下是未经测试的示例代码供您使用;我必须对Student 做出某些假设(operator&lt;&lt; 对输出有效,通过std::string country() const 暴露的国家/地区)

struct checkCountry
{
  std::string country;
  bool operator()(const Student& x) 
  {
    return (x.country() == country);
  }
};

int main()
{
  std::vector<Student> studentList;
  studentList.push_back(Student("Tom", 'M', "91213242", "America"));
  studentList.push_back(Student("Jessilyn", 'F', "98422333", "Europe"));

  typedef boost::filter_iterator<checkCountry, std::vector<Student>::iterator> FilterIter;
  checkCountry predicate;
  predicate.country = "America";
  FilterIter filter_iter_first(predicate, studentList.begin(), studentList.end());
  FilterIter filter_iter_last(predicate,  studentList.end(),  studentList.end());

  std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<Student>(std::cout, " "));
}

【讨论】:

    【解决方案3】:

    我想这就是你要找的东西:

    struct country_filter
    {
        country_filter(const std::string& a_country): country(a_country) {}
        void operator()(const Student& a_s) const
        {
            if (country == a_s.country)
            {
                std::cout << a_s.name << "\n";
            }
        }
        std::string country;
    };
    
    // 
    std::for_each(studentList.begin(), studentList.end(), country_filter("Ireland"));
    

    C++11:

    std::string country = "America";
    std::for_each(studentList.begin(), studentList.end(), [&country] (const Student& a_s)
    {
        if (a_s.country == country)
        {
            std::cout << a_s.name << "\n";
        }
    });
    

    【讨论】:

      【解决方案4】:

      您可以使用实现() 运算符的类的对象。这称为函子

      struct checkCountry {
        const string& compare;
        checkCountry(const string& compare) : compare(compare) {}
        bool operator()(const string& x) { return x == compare; }
      };
      
      vector<Student> studentList;
      studentList.push_back(Student("Tom", 'M', "91213242", "America"));
      studentList.push_back(Student("Jessilyn", 'F', "98422333", "Europe"));
      howMany = std::count_if(studentList.begin(), studentList.end(), checkCountry("America"));
      

      您可以在任何需要一元谓词的算法中使用仿函数,例如,std::count_ifstd::find_if 等。

      【讨论】:

        猜你喜欢
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 2017-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-14
        相关资源
        最近更新 更多