数据结构/算法,可以跟踪结构(x和y)和值,避免重复
C++ - Data structure/algorithm that can keep track of structures (x and y) and values avoiding duplicates
我正在寻找一个数据结构用于我正在工作的程序。它跟踪x和y值,并且只有当x,y位置不是我的数组时才需要设置Z。
我尝试使用动态数组,随着列表的增长,迭代数据变得非常非常慢。下面是我的结构。
struct pos{int x;int y;}
对应的值是一个整数,只有当x,y对不存在时才会设置。
编辑:我一直在尝试使用地图,但无法弄清楚如何使用x, y坐标有索引,即如何插入(pos, zValue);
您可以使用map,或者如果您使用c++ 11编译器,则使用unordered_map来保存点的索引
详细说明如何插入到std::map<std::pair<int, int>, int> xy_to_z_mapping;
std::pair<std::pair<int, int>, int> point(int x, int y, int z) {
return std::make_pair(std::make_pair(x,y),z);
}
xy_to_z_mapping.insert(point(x,y,z));
或
xy_to_z_mapping.insert(std::make_pair(std::make_pair(x,y),z));
或
xy_to_z_mapping[std::make_pair(x,y)] = z;
正如andre所说,要避免在结构体上重载操作符,可以使用以下映射:
std::map<std::pair<int, int>, int> a_map;
插入:
插入a_map.insert(std::pair<std::pair<int,int>, int>(std::pair<int,int>(x, y), z));
或
std::pair<int, int> index(x, y);
a_map[index] = z;
或(最简洁的版本,借用andre的回答)
a_map[make_pair(x, y)] = z;
访问:
如果你只是遍历元素,而不是特别关心通过它们的索引访问值,这种方法是很好的。如果你do想要这样做,那么你可以像这样访问它们:
std::pair<int, int> index(x, y);
int z = a_map[index];
或(最新版本)
int z = a_map[make_pair(x, y)];
您也可以使用find()
,但同样,您需要为它构建一个pair
(http://www.cplusplus.com/reference/map/map/find/)。
您可以使用<utility>
(http://www.cplusplus.com/reference/utility/make_pair/)中的make_pair()
函数使构造对更容易一些,但如果您不想使用带有成对的映射作为索引,那么您可能需要恢复到原始计划并使用std::map<pos, int>
代替。
选择地图:
如果您决定使用std::map<pos, int>
,请记住在pos
上重载operator<
,以允许map
对其键进行排序(因为您实际上没有使用任何排序功能,您可以任意返回pos::x
或pos::y
的比较)。
无序地图:
如果你想完全避免重载操作符和排序,你可以使用新的c++ 11 unordered_map
,它是一个更有效的插入和删除容器。由于您只使用map
的惟一性和迭代器属性,如果可以的话,值得考虑使用unordered_map
(它们具有非常相似的接口,并且我之前通过更改变量的类型来使用它们代替map
!)
我多少认为正确的数据结构应该是一个集合,而不是一个映射。原因是,如果您正在处理Point
s或Position
s,则数据类型包含三个坐标(x
, y
和z
)。
现在,您似乎有兴趣更新Position
的z
-坐标,只有当具有相同x
-和y
-坐标的另一个点尚未更新时。
我使用一个无序集合创建了以下实现。注意,散列器和比较器只使用x
和y
。
#include<iostream>
#include<unordered_set>
template<typename T>
struct Position {
Position(T x, T y, T z)
: x(x),
y(y),
z(z) {}
T x, y, z;
};
template<typename T>
std::ostream& operator<<(std::ostream& os, const Position<T>& p) {
os<<"("<<p.x<<", "<<p.y<<", "<<p.z<<")";
return os;
}
struct point_equal {
template<typename T>
bool operator()(const Position<T>& p1, const Position<T>& p2) const {
return (p1.x == p2.x) && (p1.y == p2.y);
}
};
struct point_hash {
template<typename T>
std::size_t operator()(const Position<T>& p) const {
std::hash<T> hasher;
return hasher(p.x) ^ hasher(p.y);
}
};
template<typename T>
class Particles {
public:
bool add(T x, T y, T z) {
return m_particles.emplace(x, y, z).second;
}
void show() const {
for(auto p : m_particles) {
std::cout<<p<<std::endl;
}
}
private:
typedef std::unordered_set<Position<T>, point_hash, point_equal> Container;
Container m_particles;
};
int main() {
Particles<int> p;
std::cout<<std::boolalpha;
std::cout<<"should show (1, 2, 3)"<<std::endl;
std::cout<<"Added new point? "<<p.add(1, 2, 3)<<std::endl;
p.show();
std::cout<<"should show (1, 2, 3) again"<<std::endl;
std::cout<<"Added new point? "<<p.add(1, 2, 4)<<std::endl;
p.show();
std::cout<<"should show (1, 2, 3) and (3, 4, 5)"<<std::endl;
std::cout<<"Added new point? "<<p.add(3, 4, 5)<<std::endl;
p.show();
std::cout<<"should show (1, 2, 3) and (3, 4, 5) again"<<std::endl;
std::cout<<"Added new point? "<<p.add(3, 4, 9)<<std::endl;
p.show();
return 0;
}
用g++ example.cpp -std=c++11
编译(使用GCC 4.7.2)我得到以下结果:
should show (1, 2, 3)
Added new point? true
(1, 2, 3)
should show (1, 2, 3) again
Added new point? false
(1, 2, 3)
should show (1, 2, 3) and (3, 4, 5)
Added new point? true
(3, 4, 5)
(1, 2, 3)
should show (1, 2, 3) and (3, 4, 5) again
Added new point? false
(3, 4, 5)
(1, 2, 3)
- 使用 yaml-cpp 更新 YAML 文档的节点和值
- 在 c++ 中对数组和值进行排序
- 使用 new 和 值进行数组初始化,但没有显式数量的元素
- C++ 宏扩展(__VA_ARGS__项名称和值)
- 井字游戏具有奇怪行为的最小最大值算法(C++)
- 将文件内容存储到unordered_map仅存储最后的项目和值
- 返回 std::tuple 中的引用和值
- 类成员的动态分配和值
- 空构造函数和值传递问题
- 检查向量是否使用除法和阻抗算法进行排序
- C++区分函子和值模板参数
- 具有默认类型和值的模板参数
- 如何用尽可能少的数据将数据缓冲区计算为零校验和值
- 演绎指南中的参考文献和值之间的差异
- 在具有 std::p air 键和值的映射中添加 b2vec2
- 在索引和值类型上参数化的惯用向量类型
- 在 openCV 矩阵中查找列最大值的索引和值
- 如何从模板获取类型和值信息
- RSA数字和字符值算法
- 数据结构/算法,可以跟踪结构(x和y)和值,避免重复