繁体   English   中英

C ++,count_if和等于

[英]C++, count_if, and equals

我有一个带有名称和数字的struct

struct S {
  string name;
  int number;
};

S对象存储在向量中。 向量根据name排序。 可能有多个具有相同name

当遍历向量中的项目时,我尝试使用count_if来检测重复项:

for(size_t i = 0; i < v.size(); ++i)
{
  const S& s = v[i];
  int count = count_if(v.begin(), v.end(), XXX);
  // do something with count
}

在上面,我不知道XXX应该是什么。 我试图创建一个谓词,但是它没有任何可比较的意义,因为它没有用:

bool IsEqualName(const S& s) {
  return s.name == ???;
}

我要查找的文档还有很多不足之处

我感觉好像缺少了很明显的东西,但是我看不到它是什么。 谁能指出我的错误?

杰夫

可以编写一个仿函数来实现此目的:

struct FindName
{
  FindName(const std::string& name) : name_(name) {}
  bool operator()(const S& s) { return s.name == name_; }

private:
  std::string name_;
};


int count = count_if(v.begin(), v.end(), FindName("noloader"));

如果您使用的是C ++ 11,请使用lambda:

int count = count_if(v.begin(), v.end(), 
                     [](const S& s){ return s.name == "noloader"; });

由于您的项目已排序,因此您可以比find_if做得更好。 在这种情况下, std::upper_bound应该可以正常工作。

由于您将S的顺序基于name因此最可能最简单的方法是重载operator<来做到这一点:

struct S { 
    string name;
    int number;

    bool operator<(S const &other) { return name < other.name; }
};

[顺便说一下,您可以在sort(v.begin(), v.end());时使用它,例如sort(v.begin(), v.end()); ]

要查找每个项目出现的次数,请从v.begin()开始,然后使用std::upper_bound查找等于第一个项目的上限,然后将要查看的范围的开头更新为迭代器upper_bound刚刚返回,并重复直到到达集合的末尾:

std::vector<size_t> counts;

auto pos = v.begin();

for (auto prev=v.begin(); prev != v.end(); prev = pos) {
    pos = std::upper_bound(prev, v.end(), *prev);
    counts.push_back(pos - prev);
}

如果您有很多重复项,那么这至少有可能会更快一些;如果您确实有很多重复项,那么这可能会快得多( upper_bound是对数的,而find_if是线性的)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM