c++如何让find_if函数能查找多个符合条件的值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++如何让find_if函数能查找多个符合条件的值?相关的知识,希望对你有一定的参考价值。
find_if只能返回第一个查找的值,如果我想返回容器里所有符合条件的值应当如何修改程序?我用指针自增的方法不起作用!!!万望详解!!在网上实在没找到,迫不得已来求助,感激不尽
我用vector存int数据时成功了但用vector存结构体时就没有输出了,这是怎么回事?
find_if算法用来查找容器内的符合条件的元素
举例如下:
第一种方式 :在仿函数的构造函数中保存要比较的值。
先写仿函数:
最后是调用find_if算法:
先包含头文件:
2. 第二种方式 :使用
binary_function 和
bind2nd
如果要对自己的仿函数使用blind2nd等适配器,必须让自己的仿函数从binary_function继承。
bind2nd表示绑定第2个参数,也可以用bind1st来绑定第一个参数。
代码示例如下:
最后是调用find_if算法:
先包含头文件:
这个例子也是先找到第一个符合条件的元素,然后再将其删除出容器。
参考技术A你可以在一个循环在连续使用find_if。 vector存结构是什么意思? 看看下面的代码:
#include<iostream>#include<vector>
#include<iterator>
#include<algorithm>
#include<string>
using namespace std;
typedef struct StudentInfo
int id;
string name;
STUINFO;
bool IsOddId (STUINFO info)
return ((info.id%2)==1);
int main(int argc, char** argv)
vector<STUINFO> v;
vector<STUINFO>::iterator iter, it_end;
STUINFO temp;
temp.id = 100;
temp.name = "Jack";
v.push_back(temp);
temp.id = 101;
temp.name = "Sam";
v.push_back(temp);
temp.id = 102;
temp.name = "John";
v.push_back(temp);
temp.id = 103;
temp.name = "Tom";
v.push_back(temp);
iter = v.begin();
it_end = v.end();
while(true)
iter = find_if(++iter, v.end(), IsOddId);
if (iter != it_end )
cout << "ID: " << (*iter).id << ", Name: " << (*iter).name <<endl;
else
break;
运行结果:
ID: 101, Name: SamID: 103, Name: Tom追问
我也是这么做的 为什么输出无结果?
呵呵,想通了就好~, begin(), end()要等到vector构造好了才行,毕竟不是array ~~~
本回答被提问者和网友采纳 参考技术B 兄弟你解决了吗,我也碰到这个问题了C++ - 迭代从 find_if 返回的 std::vector<>
【中文标题】C++ - 迭代从 find_if 返回的 std::vector<>【英文标题】:C++ - Iterating over std::vector<> returned from find_if 【发布时间】:2014-02-03 17:29:45 【问题描述】:我正在学习 C++,所以我觉得这应该是一个非常简单的答案——但我似乎找不到。所以如果我太天真了,我提前道歉。
我有一个std::vector<int>
of 值,我正在尝试查找 odd 值的索引。
我正在关注here的代码:
(以下重复):
// find_if example
#include <iostream> // std::cout
#include <algorithm> // std::find_if
#include <vector> // std::vector
bool IsOdd (int i)
return ((i%2)==1);
int main ()
std::vector<int> myvector;
myvector.push_back(10);
myvector.push_back(25);
myvector.push_back(40);
myvector.push_back(55);
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "The first odd value is " << *it << '\n';
return 0;
本示例打印第一个奇数值。 我如何扩展它以给我myvector
中每个奇数值的索引值?这是正确的方法吗?
【问题讨论】:
【参考方案1】:// find_if example
#include <iostream> // std::cout
#include <algorithm> // std::find_if
#include <vector> // std::vector
bool IsOdd (int i)
return ((i%2)==1);
int main ()
std::vector<int> myvector;
myvector.push_back(10);
myvector.push_back(25);
myvector.push_back(40);
myvector.push_back(55);
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "ODD values are: " << std::endl;
while(it != myvector.end() )
std::cout << *it << " in position " << (it - myvector.begin()) << '\n';
it = std::find_if (++it, myvector.end(), IsOdd);
return 0;
编辑:将it+1
更改为++it
请参阅@David Rodríguez - dribeas 评论如下。
【讨论】:
我需要关于距离的信息(it - myvector.begin())
。谢谢!完整阅读本文确实有助于我的理解。
nit:std::find_if(++it,...
@DavidRodríguez-dribeas 抱歉,对于这种情况,++
有什么优势?是否存在运算符'+'未重载的情况?我不明白。谢谢。
it+1
需要随机访问迭代器,这是比++it
更强的要求(只需要前向迭代器)。在这种特殊情况下,这很好,因为std::vector<>::iterator
是随机访问,但使用++it
使解决方案对其他容器可行。
it - myvector.begin()
也称为distance(myvector.begin(), it)
。 distance
可能有助于更好地了解正在发生的事情。【参考方案2】:
您可以递增it
并将其用作进一步迭代的起点:
std::cout << "odd values: ";
auto it = myvector.begin();
while(it != myvector.end())
it = std::find_if (it, myvector.end(), IsOdd);
if(it == myvector.end()) break;
std::cout << *it << ' ';
++it;
std::cout << endl;
一种更加面向算法的方法,利用copy_if
,将输出向量作为结果容器:
std::vector<int> results;
std::copy_if(myvector.begin(), myvector.end(), std::back_inserter(results), IsOdd);
现在结果包含奇数值。 (注意后面:inserter在<iterator>
标头中)
【讨论】:
您可以使用while(true)
简化循环。这样我们就不会在每次循环迭代中检查 end 两次。【参考方案3】:
您可以通过减去序列的开头来找到向量迭代器(更一般地说,任何随机访问迭代器)的索引:
std::cout << "The index is " << (it - myvector.begin()) << '\n';
更一般地说,有一个std::distance
函数可以为您提供前向迭代器之间的距离。您可以使用它,例如,如果您的容器是 list
;但您可能不想这样做,因为它会慢得多。
要查找所有奇数,您需要一个循环来再次调用find
,从刚刚找到的那个元素之后的元素开始。
【讨论】:
【参考方案4】:改变这两行:
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "The first odd value is " << *it << '\n';
变成类似:
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
while ( it != myvector.end() )
std::cout << "The next odd value is " << *it << '\n';
it = std::find_if (++it, myvector.end(), IsOdd);
【讨论】:
【参考方案5】:你需要一个循环。标准库的迭代器算法设计使这非常容易:
#include <iterator>
for (auto it = myvector.begin();
(it = std::find_if(it, myvector.end(), IsOdd)) != myvector.end(); )
std::cout << *it << " at index " << std::distance(myvector.begin(), it) << "\n";
【讨论】:
手推车挑战:你能用远程操作完成这项工作吗? :) @LightnessRacesinOrbit:“我可以”,还是“我会推荐它”吗? :-)【参考方案6】:一个不错的紧凑解决方案可能是:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main()
std::vector<int> const v1,4,9,11,2,7,8;
std::cout << "Odd values at indices";
for(auto b=begin(v), i=b, e=end(v);
(i=find_if(i,e,[](int a)return a%2==1;)) != e;
++i)
std::cout << ' ' << distance(b,i);
std::cout.flush();
【讨论】:
以上是关于c++如何让find_if函数能查找多个符合条件的值?的主要内容,如果未能解决你的问题,请参考以下文章
c++ stl 中 lower_bound 的第四个参数的用法