问题
我有一个位数组,它代表“瓷砖”的二维“地图”。此图像提供了位数组中位的图形示例:
我需要确定数组中存在多少个连续的位“区域”。在上面的示例中,有两个这样的连续“区域”,如下所示:
瓦片必须直接位于瓦片的 N、S、E 或 W 处才能被视为“连续”。对角接触的瓷砖不算在内。
到目前为止我得到了什么
因为这些位数组可能变得相对较大(大小为几 MB),所以我有意避免在我的算法中使用任何类型的递归。
伪代码如下:
LET S BE SOURCE DATA ARRAY
LET C BE ARRAY OF IDENTICAL LENGTH TO SOURCE DATA USED TO TRACK "CHECKED" BITS
FOREACH INDEX I IN S
IF C[I] THEN
CONTINUE
ELSE
SET C[I]
IF S[I] THEN
EXTRACT_AREA(S, C, I)
EXTRACT_AREA(S, C, I):
LET T BE TARGET DATA ARRAY FOR STORING BITS OF THE AREA WE'RE EXTRACTING
LET F BE STACK OF TILES TO SEARCH NEXT
PUSH I UNTO F
SET T[I]
WHILE F IS NOT EMPTY
LET X = POP FROM F
IF C[X] THEN
CONTINUE
ELSE
SET C[X]
IF S[X] THEN
PUSH TILE NORTH OF X TO F
PUSH TILE SOUTH OF X TO F
PUSH TILE WEST OF X TO F
PUSH TILE EAST OF X TO F
SET T[X]
RETURN T
我不喜欢我的解决方案的地方
- 只是为了运行,它需要两倍于它正在处理的位图数组的内存。
- 在提取“区域”时,它使用位图数组的三倍内存。
- “要检查的图块”堆栈中存在重复项 - 这看起来很难看,但不值得避免我现在拥有的方式。
我想看什么
- 更好的内存配置文件
- 更快地处理大面积
解决方案/跟进
我重新编写了仅探索边缘的解决方案(根据@hatchet 的建议)。
这实现起来非常简单——并且完全消除了跟踪“访问过的图块”的需要。
基于三个简单的规则,我可以遍历边缘,跟踪最小/最大 x 和 y 值,并在我再次到达起点时完成。
这是我使用的三个规则的演示: