如何以特定方式在 c++ STL 中查找
How to find in c++ STL in a specific manner?
map< pair<int,int> , int > m ;
在这里,pair.first
和pair.second
是积极和pair.second >= pair.first
.
我想在 map m
中找到所有迭代器,以便为给定键。键是位于对之间的整数.key例如 2 和 对是 [2,5]
和 [1,2]
等。
例如 m[1,3] = 10 , m[3,5] = 6 , m[1,8] = 9 , m[7,8] = 15
然后当我搜索m.find(3)
时,它会返回m[1,3]
、m[1,8]
、m[3,5]
的迭代器。如果没有密钥,那么它将返回m.end()
。
我不确定你为什么要这样做,但这些天提升间隔容器库非常强大。
假设您可能想要跟踪特定点的映射值的总和,您可以简单地将拆分组合样式应用于输入数据和利润:
住在科里鲁
#include <boost/icl/split_interval_map.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using Map = icl::split_interval_map<int, int>;
using Ival = Map::interval_type;
Map m;
m.add({Ival::closed(1,3), 10});
m.add({Ival::closed(3,5), 6});
m.add({Ival::closed(1,8), 9});
m.add({Ival::closed(7,8), 15});
for (auto e : m) std::cout << e.first << " -> " << e.second << "n";
std::cout << "------------------------------n";
for (auto e : boost::make_iterator_range(m.equal_range(Ival::closed(3,3))))
std::cout << e.first << " -> " << e.second << "n";
}
这将告诉我们:
[1,3) -> 19
[3,3] -> 25
(3,5] -> 15
(5,7) -> 9
[7,8] -> 24
------------------------------
[3,3] -> 25
注意如何
- 合并非常准确地反映了点
[3,3]
是唯一一个同时与输入数据的[1,3]
和[3,5]
重合的点,因此,我们在组合集合中得到半开区间([1,3)
、[3,3]
和(3,5]
(。 - 另请注意,对这一个点的查询如何正确返回您感兴趣的所有三个间隔的
10+6+9
总和。
这有什么用?
所以,你看我把问题的焦点从"怎么做?"转移到了"什么?"。它通常有助于陈述代码的目标而不是特定的机制。
当然,如果您对平均值、最小值或最大值感兴趣的不是总和,您可能会发现自己在编写一些自定义的组合策略。
奖金 如果您愿意,以下是您至少可以使用 Boost Icl:Live On Coliru 编写 OP 中提出的问题的解决方案的方法。虽然它不是特别高效,但它是直接和强大的。
我认为您可以存储(和使用(映射的相应键,而不是迭代器。如果是这样,那么代码可能看起来像
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
#include <utility>
int main()
{
std::map<std::pair<int, int>, int> m;
m[{ 1, 3}] = 10;
m[{ 3, 5}] = 6;
m[{ 7, 8}] = 15;
typedef std::map<std::pair<int, int>, int>::value_type value_type;
typedef std::map<std::pair<int, int>, int>::key_type key_type;
int search;
auto in_range = [&search]( const value_type &value )
{
return value.first.first <= search && search <= value.first.second;
};
search = 3;
std::vector<key_type> v;
v.reserve( std::count_if( m.begin(), m.end(), in_range ) );
for ( const auto &p : m )
{
if ( in_range( p ) ) v.push_back( p.first );
}
for ( const auto &p : v )
{
std::cout << "[ " << p.first << ", " << p.second << " ]" << std::endl;
}
return 0;
}
输出为
[ 1, 3 ]
[ 3, 5 ]
考虑到 key.first 小于或等于 key.second,其中 key 是映射的键。
没有办法避免从地图的开头进行线性搜索,因为如果第一个元素是 {0,INT_MAX},那么它匹配并且你想要的元素不一定在连续的范围内,例如,如果你有 {1,3},{2,2}{3,5},你只需要键为 3 时的第一个和最后一个元素。
当您到达first
大于键的元素时,可以停止搜索。
像这样的东西(未经测试(:
typedef map< pair<int,int> , int > Map;
std::vector<Map::iterator>
find(int key, const Map& m)
{
std::vector<Map::iterator> matches;
for (Map::iterator it = m.begin(), end = m.end(); it != end && key <= it->first; ++it)
{
if (it.first >= key && key <= it.second)
matches.push_back(it);
}
return matches;
}
你可以把它变成一个函子并使用find_if
但我不确定它是否值得。
如果只想每次调用返回一个迭代器:
typedef map< pair<int,int> , int > Map;
Map::iterator
find(int key, const Map& m, Map::iterator it)
{
for (Map::iterator end = m.end(); it != end && key <= it->first; ++it)
{
if (it.first >= key && key <= it.second)
return it;
}
return m.end();
}
Map::iterator
find(int key, const Map& m)
{ return find(key, m, m.begin()); }
如果你只需要一个迭代器到映射中找到的下一个值,你可以使用 std::find_if 算法,如下所示:
int key=2;
map<pair<int,int>, int>::iterator it =std::find_if(m.begin(),m.end(),
[key](pair<pair<int,int>,int> entry)
{
return (entry.first.first <= key)
&& (entry.first.second >= key);
}
);
cout << "the next value is: [" << it->first.first << "/";
cout << it->first.second << "] " << it->second << endl;
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 在C应用程序中运行C++(带有STL)函数
- 使用2个键的cpp-stl::优先级队列排序不正确
- 在STL容器中使用模板类
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 将stl字符串缩小到小于15个字符的容量
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查函数返回类型是否与STL容器类型值相同
- STL算法函数在多个一维容器上的使用
- 在STL - C++中按成绩对学生列表进行排序?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- λ可以适应STL吗?
- 为什么使用 NDK 不能存在不同的 stl 实现?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 使用 char 分隔符解析C++中的字符串,但将可重复的字符保留为每个解析的子字符串 (C++ STL) 中的分隔符
- 在C++中迭代 STL 集时出现奇怪的问题<CStudent>
- 如何在 C++17 STL 并行算法中处理调度?
- 在学习数据结构之前对STL有一个了解是好的吗?
- C++ STL 排序会检查 NaN 吗?