查找具有偶数值的矢量元素
Find vector elements with even values
你能解释一下这段代码是如何工作的吗。它成功地计算了具有偶数值的向量元素,但我不清楚在这种特殊情况下绑定是如何工作的。
count_if(vec.begin(), vec.end(),
std::bind(logical_not<bool>(),
std::bind(modulus<int>(), placeholders::_1, 2)));
请注意,您发布的代码计算向量中的偶数,而不是奇数:
count_if(vec.begin(), vec.end(), bind(logical_not<bool>(), bind(modulus<int>(), placeholders::_1, 2)));
count_if
是一种算法,它返回指定范围内满足特定标准的元素数量:
count_if(first, last, criteria)
在您的情况下,first
是vec.begin()
,last
是vec.end()
:因此计数考虑整个向量。
现在让我们把注意力集中在标准部分。
由内而外:
modulus<int>
是一个函数对象,它返回整数除法的余数(就像%
运算符一样)。它有两个参数:第一个参数表示为placeholders::_1
,它是源向量中的泛型元素。可以将其视为扫描整个矢量内容的变量x
。
第二个参数是数字2
,因为要检查整数是偶数还是奇数,可以计算x % 2
并将结果与0:进行比较
x % 2 == 0 --> even number
x % 2 == 1 --> odd number
bind
用于指定modulus
函数对象的参数。
该模运算的结果被作为另一个函数对象logical_not<bool>
的输入。这只是否定输入,例如,如果输入是false
(0),则logical_not<bool>
返回true
,反之亦然。
因此,"计数标准"由以下操作流程表示:
- 使用
modulus
计算:placeholders::_1 % 2
,即<<generic vector element>> % 2
- 如果以上操作的结果是
0
(false),则使用logical_not
返回true
(反之亦然)
所以,如果一个数字是偶数:
even number % 2 == 0
- 否定0得到
true
相反,如果一个数字是奇数:
odd number % 2 == 1
- 否定1得到
false
由于count_if
计算标准为true
的元素数,因此您正在计算向量中的偶数数。
如果你真的想计算向量中的奇数,你可以去掉逻辑反转(即logical_not
):
auto odds = count_if(vec.begin(), vec.end(),
bind(modulus<int>(), placeholders::_1, 2));
注意,在这种情况下,使用modulus
和logical_not
的函数方法似乎太复杂了:使用lambda(甚至特设IsEven()
简单函数)会更清楚
考虑以下代码(位于Ideone上)来比较这三种方法:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
bool IsEven(int n) {
return (n % 2) == 0;
}
int main() {
// Test vector
vector<int> vec{ 11, 22, 33, 44, 55 };
// Using functional approach
auto n = count_if(vec.begin(), vec.end(),
bind(logical_not<bool>(),
bind(modulus<int>(), placeholders::_1, 2)));
cout << n << endl;
// Using lambdas
n = count_if(vec.begin(), vec.end(),
[](int n) { return (n % 2) == 0; });
cout << n << endl;
// Using boolean returning ad hoc function
n = count_if(vec.begin(), vec.end(), IsEven);
cout << n << endl;
}
从内部调用到外部调用的解锁:
modulus<int>( a, 2 )
返回除以2后的余数:==0或=0.
logical_not<bool>( x )
进行x的逻辑反转(因此0/false变为1/true,1/true变为0/false)
count_if(from, to, cond )
从/到计算迭代器定义的所有元素的cond(反向模数)。
placeholders::_1
是将count_if
运行的迭代器驱动循环中确定的内容(即当前元素)插入下面嵌套的函数的硬连线方式。
这不计算奇数元素,而是偶数元素
要计算具有奇数值的矢量元素,我们必须检查每个元素是否除以2,如果结果为1,则返回true。
因此,我们将使用modulus(),它是一个实现运算符()的函数对象
constexpr T operator()( const T& lhs, const T& rhs ) const;
并返回lhs除以rhs的余数。
我们必须使用std::bind来粘合一个并且只有一个参数传递给
count_if( InputIt first, InputIt last, UnaryPredicate p )
一元谓词p
(这里是我们的模)到模的第一个自变量,常数2
到第二个
std::bind(modulus<int>(), placeholders::_1, 2))
现在我们的函数std::bind(modulus<int>(), placeholders::_1, 2))
返回true(1),如果参数是奇数,则返回false(0),如果变量是偶数。如果我们想计算偶数个自变量,我们必须忽略这一点,所以我们的谓词必须返回相反的结果:
std::bind(logical_not<bool>(),
std::bind(modulus<int>(), placeholders::_1, 2))
http://ideone.com/80VmsZ
正如Mike Seymour所建议的,更简单、更干净的设计将是用短lambda函数代替这种绑定:
[](int x){return x % 2 == 0;} // to count even elements
[](int x){return x % 2 != 0;} // to count odds
这是一个双绑定,第一个通过参数的2计算modulus
,这似乎相当于
y = x % 2
然后将结果绑定到logical_not
,以反转结果。
- 使用堆查找第K个最大元素的时间复杂性
- 查找矩阵C++中每一列和每一行的最小和最大元素
- C++如何在向量中查找最常见的元素
- 查找两个排序向量中共有的元素
- 在对向量中查找元素的索引
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 查找矩阵中单元格的相邻元素
- 为什么使用数组元素查找最大数字的程序不起作用?
- 查找第一个数组中不存在的元素
- 查找最小的下一个更大的元素
- 在最小堆中查找最大元素
- 在向量中查找大于 0(或通常为 k)的最小元素的最佳方法是什么?
- set::find 查找不存在的元素
- 在集合中查找使用结构C++的元素
- 从斐波那契序列 c++ 中的数组中查找正确的元素时出错
- 用于查找数组中最大元素的出现次数的代码,给出分段错误
- 查找数组中指示性较大但数组中值较小的元素
- C++结构集无法按元素查找/擦除
- 如何在OpenCV中使用Matlab的512元素查找表数组?
- 使用数组的元素查找总和'k'