[英]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.