簡體   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