10

根据这个网站,我希望用一个 16 位整数的二维数组来表示一个迷宫。

每个 16 位整数需要保存以下信息:

这是一种方法(这绝不是唯一的方法):12x16 迷宫网格可以表示为 16 位整数的数组 m[16][12]。每个数组元素将包含网格中单个对应单元格的所有信息,整数位映射如下:

替代文字
(来源:mazeworks.com

要推倒一堵墙、设置边界或创建特定路径,我们需要做的就是翻转一个或两个数组元素中的位。

如何在 16 位整数上使用按位标志,以便我可以设置每个位并检查它们是否已设置。

我想以一种易于阅读的方式进行(即 Border.W、Border.E、Walls.N 等)。

这通常如何在 C++ 中完成?我是否使用十六进制来表示每一个(即 Walls.N = 0x02、Walls.E = 0x04 等)?我应该使用枚举吗?


另请参阅如何设置、清除和切换单个位?.

4

8 回答 8

9

如果您想使用位域,那么这是一种简单的方法:

typedef struct MAZENODE
{
    bool backtrack_north:1;
    bool backtrack_south:1;
    bool backtrack_east:1;
    bool backtrack_west:1;
    bool solution_north:1;
    bool solution_south:1;
    bool solution_east:1;
    bool solution_west:1;
    bool maze_north:1;
    bool maze_south:1;
    bool maze_east:1;
    bool maze_west:1;
    bool walls_north:1;
    bool walls_south:1;
    bool walls_east:1;
    bool walls_west:1;
};

然后你的代码可以测试每一个的真假。

于 2009-02-13T18:34:19.073 回答
7

采用std::bitset    

于 2009-02-14T09:12:22.113 回答
3

如果您关心哪些特定位的含义,请使用十六进制常量/枚举和按位运算。

否则,使用 C++ 位域(但请注意,整数中位的顺序将取决于编译器)。

于 2009-02-13T18:13:43.600 回答
2

了解您的位运算符:&、|、^ 和 !。

在许多 C/C++ 文件的顶部,我看到了以十六进制定义的标志来屏蔽每一位。

#define ONE 0x0001

要查看某个位是否打开,请与 1 进行“与”。要打开,请与 1 进行或。要像开关一样切换,请与 1 进行异或。

于 2009-02-13T18:17:09.050 回答
2

要操作位集,您还可以使用 ....

std::bitset<N>

std::bitset<4*4> bits;
bits[ 10 ] = false;
bits.set(10);
bits.flip();
assert( !bits.test(10) );
于 2009-03-20T12:16:56.587 回答
1

您可以按照您的建议使用十六进制标志或枚举来执行此操作,但最易读/自我记录的可能是使用所谓的“位域”(有关详细信息,Google for C++ bitfields)。

于 2009-02-13T18:10:11.800 回答
1

是的,一个好方法是使用十六进制十进制来表示位模式。然后使用位运算符来操作 16 位整数。

例如:

if(x & 0x01){} // tests if bit 0 is set using bitwise AND
x ^= 0x02;     // toggles bit 1 (0 based) using bitwise XOR
x |= 0x10;     // sets bit 4 (0 based) using bitwise OR
于 2009-02-13T18:15:09.197 回答
0

我不是 bitset 的忠实粉丝。在我看来,这只是更多的打字。无论如何,它并没有隐藏你在做什么。你还是要 & && | 位。除非您只选择 1 位。这可能适用于一小组标志。并不是说我们也需要隐藏我们正在做的事情。但是一个类的目的通常是让它的用户更容易做一些事情。我不认为这门课能做到。

例如,您有一个带有 .. 64 个标志的标志系统。如果你想测试..我不知道.. 1 if 语句中有 39 个,看看它们是否都在......使用位域是一个巨大的痛苦。你必须把它们都打出来……当然。我假设你只使用位域功能,而不是混合和匹配方法。与位集相同。除非我在课堂上遗漏了一些东西。这是很有可能的,因为我很少使用它。我看不到一种可以测试所有 39 个标志的方法,除非你输入洞的东西或诉诸“标准方法”(使用枚举标志列表或 39 位的一些定义值并使用位集 && 运算符)。根据您的方法,这可能会开始变得混乱。我知道.. 64 个标志听起来很多。好吧。它是..取决于你在做什么。就个人而言,我参与的大多数项目都依赖于标志系统。所以实际上.. 64 并不是闻所未闻的。虽然 16~32 在我的经验中更为常见。实际上,我现在正在帮助一个标志系统具有 640 位的项目。它基本上是一个特权系统。

于 2009-05-19T04:12:08.297 回答