STL 统计vector容器中指定对象元素出现的次数:count()与count_if()算法

25 篇文章 1 订阅
8 篇文章 0 订阅

1 统计vector向量中指定元素出现的次数:count()算法

   利用STL通用算法统计vector向量中某个元素出现的次数:count()算法统计等于某个值的对象的个数

#include "stdafx.h"

#include <iostream>

#include <vector>

#include <algorithm> //包含通用算法

using namespace std;

int_tmain(int argc, _TCHAR* argv[])

{

    vector<int> scores;

    scores.push_back(100);

    scores.push_back(80);

    scores.push_back(45);

    scores.push_back(75);

    scores.push_back(99);

    scores.push_back(100);

    int num = 0;

    num= count(scores.begin(),scores.end(),100);//统计100出现的次数

    cout<<"times: "<<num<<endl;

    return 0;

}

2 count_if():利用函数对象统计满足条件对象的个数

函数对象是一个至少带有一个operator()方法的类。

函数对象被约定为STL算法调用operator时返回true或false,它们根据这个来判定这个函数。

count_if()函数通过传递一个函数对象来做出比count()统计函数更加复杂的评估以确定一个对象是否应该被计数,即count_if()函数的功能等同于count()函数和一些条件语句。

例子:1

#include "stdafx.h"

#include <iostream>

#include <vector>

#include <algorithm>

#include <string>

using namespace std;

conststring TC("0003");

classIsTB

{

public:

    IsTB(){cout<<"执行默认构造函数"<<endl;}

    bool operator()(string& saleRecord)

    {

       return (saleRecord.substr(0,4) == TC);

    }

};

int_tmain(int argc, _TCHAR* argv[])

{

    vector<string>saleRecordVec;

    saleRecordVec.push_back("0001 Soap");

    saleRecordVec.push_back("0002 Shampoo");

    saleRecordVec.push_back("0003 ToothBrush");

    saleRecordVec.push_back("0004 Toothpaste");

    saleRecordVec.push_back("0003 ToothBrush");

    int num = 0;

    num= count_if(saleRecordVec.begin(),saleRecordVec.end(),IsTB());

    cout<<"Times: "<<num<<endl;

    IsTBobjIsTB;

    //利用已有的对象

    num= count_if(saleRecordVec.begin(),saleRecordVec.end(),objIsTB);

    cout<<"Times: "<<num<<endl;

 

    return 0;

}

count_if()函数的第三个参数是类对象。

执行结果:

 

如果需要给函数对象传递更多的信息,那么可以通过定义一个非缺省的构造函数来初始化所需要的信息。

例子:2

#include "stdafx.h"

#include <iostream>

#include <vector>

#include <algorithm>

#include <string>

using namespace std;

classIsTB

{

public:

    IsTB(string& str){ m_str =str;} //通过构造函数传递信息

    bool operator()(string&saleRecord)

    {

       return (saleRecord.substr(0,4) == m_str);

    }

private:

    stringm_str;

};

 

int_tmain(int argc, _TCHAR* argv[])

{

    vector<string>saleRecordVec;

    saleRecordVec.push_back("0001 Soap");

    saleRecordVec.push_back("0002 Shampoo");

    saleRecordVec.push_back("0003 ToothBrush");

    saleRecordVec.push_back("0004 Toothpaste");

    saleRecordVec.push_back("0003 ToothBrush");

    int num = 0;

    stringstr("0003");

    num= count_if(saleRecordVec.begin(),saleRecordVec.end(),IsTB(str));

    cout<<"Times: "<<num<<endl;

    IsTBobjIsTB(str);

    //利用已有的对象

    num= count_if(saleRecordVec.begin(),saleRecordVec.end(),objIsTB);

    cout<<"Times: "<<num<<endl;

 

    return 0;

}

 

 

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
不知道网上有没有Effective STL(文),我找不到,我自己整理出了这个《Effective STL(文)》共享给需要的人。<br><br>《Effective STL》目录:<br><br>前言<br>致谢<br>导读<br>容器<br>条款1:仔细选择你的容器<br>条款2:小心对“容器无关代码”的幻想<br>条款3:使容器对象的拷贝操作轻量而正确<br>条款4:用empty来代替检查size()是否为0<br>条款5:尽量使用区间成员函数代替它们的单元素兄弟<br>条款6:警惕C++最令人恼怒的解析<br>条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针<br>条款8:永不建立auto_ptr的容器<br>条款9:在删除选项仔细选择<br>条款10:注意分配器的协定和约束<br>条款11:理解自定义分配器的正确用法<br>条款12:对STL容器线程安全性的期待现实一些<br>vector和string<br>条款13:尽量使用vector和string来代替动态分配的数组<br>条款14:使用reserve来避免不必要的重新分配<br>条款15:小心string实现的多样性<br>条款16:如何将vector和string的数据传给传统的API<br>条款17:使用“交换技巧”来修整过剩容量<br>条款18:避免使用vector<bool><br>关联容器<br>条款19:了解相等和等价的区别<br>条款20:为指针的关联容器指定比较类型<br>条款21:永远让比较函数对相等的值返回false<br>条款22:避免原地修改set和multiset的键<br>条款23:考虑使用有序vector代替关联容器<br>条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择<br>条款25:熟悉非标准散列容器<br>迭代器<br>条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator<br>条款27:用distance和advance把const_iterator转化成iterator<br>条款28:了解如何通过reverse_iterator的base得到iterator<br>条款29:需要一个一个字符输入时考虑使用istreambuf_iterator<br>算法<br>条款30:确保目标区间足够大<br>条款31:了解你的排序选择<br>条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase<br>条款33:提防在指针的容器上使用类似remove的算法<br>条款34:注意哪个算法需要有序区间<br>条款35:通过mismatch或lexicographical比较实现简单的忽略大小写字符串比较<br>条款36:了解copy_if的正确实现<br>条款37:用accumulate或for_each来统计区间<br>仿函数、仿函数类、函数等<br>条款38:把仿函数类设计为用于值传递<br>条款39:用纯函数做判断式<br>条款40:使仿函数类可适配<br>条款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因<br>条款42:确定less<T>表示operator<.<br>使用STL编程<br>条款43:尽量用算法调用代替手写循环<br>条款44:尽量用成员函数代替同名的算法<br>条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别<br>条款46:考虑使用函数对象代替函数作算法的参数<br>条款47:避免产生只写代码<br>条款48:总是#include适当的头文件<br>条款49:学习破解有关STL的编译器诊断信息<br>条款50:让你自己熟悉有关STL的网站<br>参考书目<br>附录A:区域设置和忽略大小写的字符串比较<br>附录B:在微软STL平台上的注意事项<br>词汇表<br>索引<br>关于本电子书
effective stl pdf 怎么使用stl 这里几乎都有说明 条款1: 仔细选择你要的容器 条款2: 小心对“容器无关代码”的幻想 条款3: 使容器对象的拷贝操作轻量而正确 条款4: 用empty来代替检查size是否为0 条款5: 尽量使用范围成员函数代替他们的单元素兄弟 条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前delete那些指针 条款8: 千万不要把auto_ptr放入容器 条款9: 小心选择删除选项 条款10: 当心allocator的协定和约束 条款11: 了解自定义allocator的正统使用法 条款12: 对STL容器的线程安全性的期待现实一些 vector和string 条款13: 尽量使用vector和string来代替动态申请的数组 条款14: 用reserve来避免不必要的内存重新分配 条款15: 当心string的实现的变化 条款16: 如何将vector和string的数据传给传统的API 条款17: 用“交换技巧”来修正过度的容量 条款18: 避免使用vector<bool> 关联容器 条款19: 了解相等和等价的区别 条款20: 为包含指针的关联容器指定比较类型 条款21: 永远让比较函数对相等的值返回false 条款22: 避免对set和multiset的键值进行修改 条款23: 考虑用排序的vector代替关联容器 条款24: 当效率很关键时尽量用map::insert代替map::operator 条款25: 让自己熟悉非标准的hash容器 迭代器 条款26: 尽量使用iterator代替const_iterator,reverse_iterator和const_reverse_iterator 条款27: 使用distance和advance把const_iterators转化成iterators 条款28: 了解如何通过reverse_iterator的base得到iterator 条款29: 需要一字符一字符输入时请用istreambuf_iterator 算法 条款30: 确保目的范围足够大 条款31: 了解你的排序选项 条款32: 如果你真的想删除东西的话在remove-like的算法后紧接上erase 条款33: 当心在包含指针的容器使用remove-like的算法 条款34: 注意哪些算法需要排序过的范围 条款35: 通过mismatch或lexicographical_compare实现简单的忽略大小写字符串比较 条款36: 用not1和remove_copy_if来表现copy_if 条款37: 用accumulate或for_each来统计序列 仿函数,仿函数类,函数等等 条款38: 把仿函数类设计成值传递的 条款39: 用纯函数做predicate 条款40: 增强仿函数类的适应性 条款41: 明确ptr_fun, mem_fun和mem_fun_ref的区别 条款42: 保证less是operator<的意思 用STL编程 条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的参数 条款47: 避免产生只写代码 条款48: 总是#include适当的头文件 条款49: 学会破解STL相关的编译器出错信息 条款50: 让自己熟悉STL相关的网站
std::count_if 是 STL 的一个算法,用于对容器元素进行条件统计。它的函数原型如下: ```c++ template <class InputIterator, class Predicate> typename iterator_traits<InputIterator>::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); ``` 其,first 和 last 分别表示容器要进行统计元素范围,pred 是一个谓词函数,用于对容器的每个元素进行判断。count_if 函数会遍历容器的每个元素,对每个元素都调用谓词函数 pred 进行判断,如果返回值为 true,则该元素被认为是符合条件的,计入统计结果。 count_if 函数返回符合条件的元素个数,其类型为 iterator_traits<InputIterator>::difference_type,表示两个迭代器之间的距离,通常是一个整型数。 下面是一个简单的例子,用于说明 std::count_if 算法的用法: ```c++ #include <iostream> #include <vector> #include <algorithm> bool isOdd(int num) { return num % 2 == 1; } int main() { std::vector<int> vec = {1, 2, 3, 4, 5}; // 使用 std::count_if 算法和 isOdd 谓词函数,统计 vec 奇数的个数 int count = std::count_if(vec.begin(), vec.end(), isOdd); std::cout << "Count: " << count << std::endl; return 0; } ``` 在这个例子,我们定义了一个谓词函数 isOdd,用于判断一个数是否为奇数。然后,我们使用 std::count_if 算法和 isOdd 谓词函数来统计 vec 容器奇数的个数。在调用 std::count_if 算法时,需要传入谓词函数 isOdd 作为第三个参数,表示对容器的每个元素都要调用该函数进行判断。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值