Проблема
У меня есть бит-массив, который представляет собой двумерную "карту" "плиток". Это изображение представляет собой графический пример бит в массиве бит:
Мне нужно определить, сколько смежных "областей" бит существует в массиве. В приведенном выше примере есть две такие смежные "области", как показано здесь:
Плитки должны быть расположены непосредственно N, S, E или W плитки, которые считаются "смежными". Диагонально трогательные плитки не учитываются.
Что у меня до сих пор
Поскольку эти битовые массивы могут стать относительно большими (несколько мегабайт), я намеренно избегал использования какой-либо рекурсии в моем алгоритме.
Псевдокод выглядит следующим образом:
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
Что мне не нравится в моем решении
- Просто для запуска он требует в два раза больше памяти обрабатываемого массива битмапов.
- При извлечении "area" он использует три раза память массива битмапов.
- Дубликаты существуют в стеке, чтобы проверить "стек", что кажется уродливым, но не стоит избегать того, как у меня сейчас есть.
Что я хотел бы видеть
- Улучшенный профиль памяти
- Более быстрая обработка больших площадей.
Решение/последующее наблюдение
Я повторно написал решение, чтобы исследовать только края (за каждое предложение @hatchet).
Это было очень просто реализовать - и устраняли необходимость полностью отслеживать "посещенные плитки".
Основываясь на трех простых правилах, я могу пересекать края, отслеживать значения min/max x и y и заканчивать, когда я снова прихожу к началу.
Здесь демо с тремя правилами, которые я использовал: