Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-数据结构/算法,可跟踪结构(x和y)和值,避免重复_C++_Algorithm_Data Structures - Fatal编程技术网

C++ C++;-数据结构/算法,可跟踪结构(x和y)和值,避免重复

C++ C++;-数据结构/算法,可跟踪结构(x和y)和值,避免重复,c++,algorithm,data-structures,C++,Algorithm,Data Structures,我正在寻找一个数据结构,用于我的工作程序。它跟踪x和y值,并且仅当x,y位置还不是我的数组时才需要设置Z 我尝试使用动态数组,随着列表的增长,遍历数据的速度变得非常慢。这就是我的结构 结构位置 { int x; int-y; } 对应的值是一个整数,仅当x,y对不存在时才设置 编辑:我一直在尝试使用地图,但不知道如何使用具有索引的x,y坐标,即如何插入(pos,zValue) > P>你可以使用一个地图或者如果你使用一个C++ 11编译器来保持一个点的索引。 < P>你可以使用一个地图或者如果你

我正在寻找一个数据结构,用于我的工作程序。它跟踪x和y值,并且仅当x,y位置还不是我的数组时才需要设置Z

我尝试使用动态数组,随着列表的增长,遍历数据的速度变得非常慢。这就是我的结构

结构位置 { int x; int-y; }

对应的值是一个整数,仅当x,y对不存在时才设置


编辑:我一直在尝试使用地图,但不知道如何使用具有索引的x,y坐标,即如何插入(pos,zValue)

> P>你可以使用一个地图或者如果你使用一个C++ 11编译器来保持一个点的索引。

< P>你可以使用一个地图或者如果你使用一个C++ 11编译器,一个无序的地图来保持点的索引。

< P>正如安德烈所说,为了避免你的结构上的重载操作符,你可以使用下面的映射:

std::map a_map

插入:

a_映射插入(std::pair(std::pair(x,y,z))

std::对索引(x,y);
a_映射[索引]=z

或者(最简洁的版本,借用安德烈的答案)

a_图[make_对(x,y)]=z

访问:

如果您只是在元素中进行迭代,并且不特别关心经常通过元素的索引访问值,那么这种方法就可以了。如果您确实想这样做,那么您可以这样访问它们:

std::对索引(x,y);
intz=a_映射[索引]

或(最新版本)

intz=a_映射[make_对(x,y)]

您也可以使用
find()
,但同样,您需要为它构建一对
对()

您可以使用
()中的
make_pair()
函数来简化对的构造,但是如果您不想使用带有对的映射作为索引,那么您可能需要恢复到原始计划,并使用
std::map

备选地图:


如果您决定使用
std::map
只需记住重载
操作符,正如andre所说,为了避免在结构上重载操作符,您可以使用以下映射:

std::map a_map

插入:

a_映射插入(std::pair(std::pair(x,y,z))

std::对索引(x,y);
a_映射[索引]=z

或者(最简洁的版本,借用安德烈的答案)

a_图[make_对(x,y)]=z

访问:

如果您只是在元素中进行迭代,并且不特别关心经常通过元素的索引访问值,那么这种方法就可以了。如果您确实想这样做,那么您可以这样访问它们:

std::对索引(x,y);
intz=a_映射[索引]

或(最新版本)

intz=a_映射[make_对(x,y)]

您也可以使用
find()
,但同样,您需要为它构建一对
对()

您可以使用
()中的
make_pair()
函数来简化对的构造,但是如果您不想使用带有对的映射作为索引,那么您可能需要恢复到原始计划,并使用
std::map

备选地图:


如果您决定使用
std::map
请记住重载
操作符,以充分说明如何插入
std::map xy_到_z_映射

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));
或者


充分阐述如何插入到
std::map xy_到_z_映射中

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));
或者


我有点认为正确的数据结构似乎是一个集合,而不是一张地图。原因是,如果处理的是
s或
位置
s,则数据类型包含三个坐标(
x
y
z

现在,您似乎有兴趣更新
位置
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;
}

我有点认为正确的数据结构似乎是一个集合,而不是一张地图。原因是,如果处理的是
s或
位置
s,则数据类型包含三个坐标(
x
y
z

现在,您似乎有兴趣更新
位置
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;
}

也许是多重地图。这将允许您快速搜索是否存在任何对,但也允许您存储多个相同的对。但我不完全确定我是否理解。是的,重新阅读你的问题std::map似乎是正确的。
std::map xy_到_z_映射避免使用自己的类型和提供比较运算符。是的,使用重载。您需要这样做的原因是std::map是一个排序容器,因此您需要提供一种确定排序顺序的方法。如果您只想要唯一性属性和迭代能力,那么最好使用无序映射btw(前提是您可以访问C++11编译器)。插入和删除速度更快。std:multimap可能吧。这将允许您快速搜索是否存在任何对,但也允许您存储多个相同的对。但我不完全确定我是否理解
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)