C++ std::map:由具有相等值的键组成的返回向量
我有一个C++ std::map:由具有相等值的键组成的返回向量,c++,algorithm,dictionary,duplicates,stdmap,C++,Algorithm,Dictionary,Duplicates,Stdmap,我有一个std::map对象。关键点是实体ID(整数)及其二维位置(向量)的值。目的是确定哪些实体处于 相同的位置 ID位置 1 {2,3} 5 {6,2} 12 {2,3} 54 {4,4} 92 {6,2} 我需要得到一个向量,向量由键组成,它们的值相等 上面示例输入数据的输出:{1,12},{5,92} 我知道我可以将2D位置复制到向量到向量,并循环第一级向量以找到相等的第二级向量的索引。然后,通过索引选择向量并再次循环找到相应的键,返回查找键 请建议一种更干净的方法。标准
std::map
对象。关键点是实体ID(整数)及其二维位置(向量)的值。目的是确定哪些实体处于
相同的位置
ID位置
1 {2,3}
5 {6,2}
12 {2,3}
54 {4,4}
92 {6,2}
我需要得到一个向量,向量由键组成,它们的值相等
上面示例输入数据的输出:{1,12},{5,92}
我知道我可以将2D位置复制到向量到向量,并循环第一级向量以找到相等的第二级向量的索引。然后,通过索引选择向量并再次循环找到相应的键,返回查找键
请建议一种更干净的方法。标准::映射的要点是提供有效的键到值的映射。您需要的是一个额外的键映射值-可以通过多种方式实现:
- 有一个额外的
,从std::map
到Position
std::vector
- 使用某种空间分区数据结构(例如四叉树、空间哈希、网格),可以根据实体的位置高效地查找实体
- 使用双向多贴图类似。这将允许您在值集合上进行双向映射,而不必使用多个数据结构
这取决于你的优先级。如果您想获得最大的性能,应该尝试所有的方法(可能使用某种模板化包装器)和配置文件。如果您想要优雅/整洁,
boost::bimap
似乎是最合适的解决方案。std::map
的要点是提供有效的键到值的映射。您需要的是一个额外的键映射值-可以通过多种方式实现:
- 有一个额外的
,从std::map
到Position
std::vector
- 使用某种空间分区数据结构(例如四叉树、空间哈希、网格),可以根据实体的位置高效地查找实体
- 使用双向多贴图类似。这将允许您在值集合上进行双向映射,而不必使用多个数据结构
这取决于你的优先级。如果您想获得最大的性能,应该尝试所有的方法(可能使用某种模板化包装器)和配置文件。如果您想要优雅/整洁,
boost::bimap
似乎是最合适的解决方案。您可以将地图中的数据放入std::mutlimap
,其中位置
作为键,ID
作为值
作为旁注,我想知道对于二维点而言,std::pair是否比向量更好。您可以将地图中的数据放入
std::mutlimap
,其中位置
作为键,ID
作为值
作为旁注,我想知道对于二维点,std::pair是否比向量更好。您需要提供反向映射。有很多方法可以做到这一点,包括
multimap
,但是如果在创建映射后没有修改映射,一个简单的方法是迭代映射并构建反向映射。在反向映射中,映射值->键列表
下面的代码使用std::unordered_map
将std::pair
(原始映射中的值)映射到std::vector
(原始映射中的键列表)。反向地图的构建简单明了:
std::unordered_map<Point, std::vector<int>, hash> r;
for (const auto& item : m) {
r[item.second].push_back(item.first);
}
您需要提供一个反向映射。有很多方法可以做到这一点,包括
multimap
,但是如果在创建映射后没有修改映射,一个简单的方法是迭代映射并构建反向映射。在反向映射中,映射值->键列表
下面的代码使用std::unordered_map
将std::pair
(原始映射中的值)映射到std::vector
(原始映射中的键列表)。反向地图的构建简单明了:
std::unordered_map<Point, std::vector<int>, hash> r;
for (const auto& item : m) {
r[item.second].push_back(item.first);
}
似乎是最好的,但我还是会提供我的代码
给定
#包括
#包括
#包括
//向量2D的一些定义
结构向量2d{intx;inty;};
//向量2D上算子<的一些定义
布尔运算符b.x)返回false;
返回a.y
那么:
template <typename M>
auto calculate(M const & inputMap) -> std::vector<std::vector<typename M::key_type> > {
std::map<typename M::mapped_type,
std::vector<typename M::key_type> > resultMap;
for (auto const & vp : inputMap)
resultMap[vp.second].push_back(vp.first);
std::vector<std::vector<typename M::key_type> > result;
for (auto & vp: resultMap)
if (vp.second.size() > 1)
result.emplace_back(std::move(vp.second));
return result;
}
模板
自动计算(M常量和输入映射)->std::vector{
映射结果映射;
用于(自动常量和vp:inputMap)
结果映射[vp.second]。推回(vp.first);
std::向量结果;
用于(自动和vp:resultMap)
如果(vp.second.size()>1)
结果:后置(标准::移动(副总裁秒));
返回结果;
}
以下是如何测试:
int main() {
std::map<int, Vector2D> input{
{1, Vector2D{2,3}},
{5, Vector2D{6,2}},
{13, Vector2D{2,3}},
{54, Vector2D{4,4}},
{92, Vector2D{6,2}}
};
auto const result = calculate(input);
// Ugly print
std::cout << '{';
static auto const maybePrintComma =
[](bool & print) {
if (print) {
std::cout << ", ";
} else {
print = true;
}
};
bool comma = false;
for (auto const & v: result) {
maybePrintComma(comma);
std::cout << '{';
bool comma2 = false;
for (auto const & v2: v) {
maybePrintComma(comma2);
std::cout << v2;
}
std::cout << '}';
}
std::cout << '}' << std::endl;
}
intmain(){
映射输入{
{1,向量2d{2,3},
{5,向量2d{6,2},
{13,向量2d{2,3},
{54,向量2d{4,4},
{92,向量2d{6,2}
};
自动常数结果=计算(输入);
//丑陋的印刷品
std::cout似乎是最好的,但无论如何我都会提供我的代码
给定
#包括
#包括
#包括
//向量2D的一些定义
结构向量2d{intx;inty;};
//向量2D上算子<的一些定义
布尔运算符b.x)返回false;
返回a.y
那么:
template <typename M>
auto calculate(M const & inputMap) -> std::vector<std::vector<typename M::key_type> > {
std::map<typename M::mapped_type,
std::vector<typename M::key_type> > resultMap;
for (auto const & vp : inputMap)
resultMap[vp.second].push_back(vp.first);
std::vector<std::vector<typename M::key_type> > result;
for (auto & vp: resultMap)
if (vp.second.size() > 1)
result.emplace_back(std::move(vp.second));
return result;
}
模板
自动计算(M常量和输入映射)->std::vector{
映射结果映射;
用于(自动常量和vp:inputMap)
结果映射[vp.second]。推回(vp.first);
std::向量结果;
用于(自动和vp:resultMap)
如果(vp.second.size()>1)
结果:后置(标准::移动(副总裁秒));
返回结果;
}