【发布时间】:2012-03-22 09:46:41
【问题描述】:
我有一个元组列表,该列表是根据元组的第一个元素排序的,但第二个和最后一个元素是随机顺序的。现在我想找到一个范围内第一个元素的所有元组,即返回(tuple.first>-X 和tuple.first<X)的所有元组。在所有这些返回的元组中,我需要在元组的第二个元素中找到最大值和最小值。 STL 算法如何实现这一点?
【问题讨论】:
我有一个元组列表,该列表是根据元组的第一个元素排序的,但第二个和最后一个元素是随机顺序的。现在我想找到一个范围内第一个元素的所有元组,即返回(tuple.first>-X 和tuple.first<X)的所有元组。在所有这些返回的元组中,我需要在元组的第二个元素中找到最大值和最小值。 STL 算法如何实现这一点?
【问题讨论】:
ListType::iterator itrFirst = std::find_if( ls.begin(), ls.end(), boost::bind( &TupleType::get< 0 >, _1 ) >= rangeStart );
ListType::iterator itrLast = std::find_if( itrFirst, ls.end(), boost::bind( &TupleType::get< 0 >, _1 ) > rangeEnd );
for( ;itrFirst != itrLast; ++itrFirst ) // Print keys for elements in range
std::cout << itrFirst->get<0>() << std::endl;
如果你有最新的编译器(我没有),我认为 boost:: 可以替换为 std::。
【讨论】:
由于它已经排序,您可以使用equal_range 来获得一对划定“有趣”元组范围的迭代器:
It const begin = std::lower_bound(list.begin(), list.end(),
[X](Tuple const& t) {
return t.first > -X;
});
It const end = std::upper_bound(begin, list.end(),
[X](Tuple const& t) {
return t.first < X;
});
std::pair<It,It> const range = std::make_range(begin, end);
然后,您可以简单地迭代此范围,并注册您看到的最小值和最大值:
int min = INT_MAX, max = INT_MIN;
for (Tuple const& t: range) {
if (t.second < min) { min = t.second; }
if (t.second > max) { max = t.second; }
}
// min and max are correctly set
所以...这不是一个单一的 STL 算法。
注意:std::min_element 和 std::max_element 确实存在,但这意味着在该范围内循环两次,但这当然是可行的。
Tuple const& min = *std::min_element(range.first, range.second,
[](Tuple const& left, Tuple const& right) {
return left.second < right.second;
});
Tuple const& max = *std::max_element(range.first, range.second,
[](Tuple const& left, Tuple const& right) {
return left.second < right.second;
});
// Or as noted by Vitali, slightly more efficient:
auto const minmax = std::minmax_element(range.first, range.second,
[](Tuple const& left, Tuple const& right) {
return left.second < right.second;
});
Tuple const& min = *minmax.first;
Tuple const& max = *minmax.second;
请注意,它给出的是一个元组,而不是 .second 成员。
【讨论】:
lower_bound 和 `upper_bound。