繁体   English   中英

在C ++中使用简单数组?

[英]Simple array use in C++?

我有一个正方形的网格。 每个正方形都是黑色或白色。 网格的范围从X:-10到10,Y:-10到10。我想用2D布尔数组表示网格-黑色为真,白色为假。 数组索引不过是正数-因此,如果我想用数组创建网格,那就是bool array [21][21] 这项工作可以完成,但是当我尝试访问一个元素时会感到困惑。 例如,如果我要访问网格上的坐标“ 0,3”,则数组索引将为[11] [14]。 这行得通,但确实很混乱。

有什么“清洁”的方法可以使索引与坐标相对应?

您可以将逻辑封装到提供所需接口的类中。 为了使它有点通用,您可以考虑要存储的类型和尺寸可能有所不同:

 template <typename T, int DimX, int DimY>
 class offset_array2d
 {
    T data[ DimX*DimY ];
    static const int offset_x = DimX / 2;
    static const int offset_y = DimY / 2;
 public:
    offset_array2d() : data() {}
    T& operator()( int x, int y ) {
       return data[ (x+offset_x) + (y+offset_y)*DimY ];
    }
    T const & operator()( int x, int y ) const {
       return data[ (x+offset_x) + (y+offset_y)*DimY ];
    }
 };

实现可能需要一些细节,但是总的想法就在那里。 应该有错误报告和更多内容...可以将维度设置为运行时属性(而不是模板参数),但是这需要动态分配,适当的析构函数和复制构造函数...我真的不想深入探讨所有这些只是想法。

范围的另一端是用户代码,现在这很简单:

 int main() {
    offset_array2d<bool,21,21> board;
    for ( int i = -10; i < 11; ++i )
      board( i, i ) = true;          // write the diagonal
 }

您可以简单地通过函数访问数组,该函数将计算数组中的正确偏移量(将x和y加10):

bool grid[21][21];

bool getSquareColour(size_t x, size_t y)
{
   // add bounds checking here
   return grid[x+10][y+10];
}

设置正方形也是如此。 我将所有这些包装到Grid类中。

您可能还想使用std::vector<bool>而不是bool[] ,后者会将每个bool存储为单独的位,并为您提供std::vector类的额外(可能是不需要的)功能。

你应该做一个助手功能

#define OFFSET 10

void place_elem(int x, int y, bool color){

     //put bounds checks here
     a[OFFSET+x][OFFSET+y] = color;

}

所以

place_elem(0, -3, true) == (a[10][7] = true)

如果您担心对数组的每次更改都进行函数调用的开销,那么可以改用宏:

#define PLACE_ELEM(x, y, c) (a[OFFSET+x][OFFSET+y] = c)

但是,除非您完全了解使用宏的安全问题,否则请不要这样做。 另外,如果您使用的是C99或C ++,则可以使用内联方法/函数。 这将做同样的事情,但是没有危险。

而且,枚举可能比布尔更好

认为:

enum Color {BLACK, WHITE};

我很确定这会引起未定义的行为。 我也很确定这可以在我关心的每种架构上使用。

#include <cassert>


int main () {
   bool grid_[21][21];
   bool (*grid)[21];

   grid = (bool (*)[21])(&grid_[10][10]);
   assert(&grid_[0][0] == &grid[-10][-10]);
   assert(&grid_[0][20] == &grid[-10][10]);
   assert(&grid_[20][20] == &grid[10][10]);
}

只是提供一个简单易用的替代答案(但是很难实现和维护),创建一个C ++类,用getter和setter隐藏复杂性。 您还可以考虑重载运算符。 由于该字段是二进制的,因此我选择使用按位运算来打包数据:

class SimpleArray
{
public:
  SimpleArray()
  {
    memset(data, 0, sizeof(data));
  }

  void set(int x, int y, bool value)
  {
    if (x >= -10 && x <= 10 && y >= -10 && y <= 10)
    {
      if (value)
      {
          data[y + 10] |= (1 << (x + 10));
      }
      else
      {
          data[y + 10] &= ~(1 << (x + 10));
      }
    }
  }

  bool get(int x, int y)
  {
    if (x >= -10 && x <= 10 && y >= -10 && y <= 10)
    {
      return (data[y + 10] & (1 << (x + 10))) != 0;
    }
    return false;
  }

  private:
    unsigned int data[21];
};

与其增加/减少索引,不如创建一个整数映射(map),在该映射中您将为特定值分配特定索引。

然后,您将为平方值传递地图的值(例如,在平方表中为键值-10 => 0(索引)传递地图的结果)。

您在这里有一个地图示例: http : //www.yolinux.com/TUTORIALS/CppStlMultiMap.html

当然,地图使用的内存比简单函数要多,但可重用性更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM