algorithm - How to effectively find areas in two-dimensional array? -


i need idea how find areas below marked 0 in two-dimensional array. should noted there other areas, such picture shows 1 of 2 owns coordinate (0.0) , other owns coordinate (21.3).

00000000000111110000111 00000000001111110000111 00000000011111100000111 00000000000111000001101 00000000011100000011101 00000001111100001111001 00000111111111011111001 00000001111100001111001 00000000010000000011001 00000000000000000001111 

of course real array larger. recursive version goes sides , stops @ mark 1 or array side isn't fast enough.

it looks you're looking flood-fill algorithm. wikipedia page linked lists few algorithms may faster obvious recursive method.

flood-fill match if areas you're looking small compared entire array, , don't need search all of them. if need know or of them, computing them in single shot using union-merge based connected component labeling algorithm may better choice. here's code implements such algorithm (note i've altered run in single pass):

#include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <map>  const char *data[] = { "00000000000111110000111", "00000000001111110000111", "00000000011111100000111", "00000000000111000001101", "00000000011100000011101", "00000001111100001111001", "00000111111111111111001", "00000001111100001111001", "00000000010000000011001", "00000000000000000001111", null };  struct label { private:     int index;     int rank;     label *parent; public:     label ()         : index(-1), rank(0), parent(this)     { }      int getindex(int &maxindex) {         if (parent != this)             return find()->getindex(maxindex);          if (index < 0)             index = maxindex++;         return index;     }      label *find() {         if (parent == this)             return this;          parent = parent->find();         return parent;     }      label *merge(label *other)     {         label *xroot = find();         label *yroot = other->find();          if (xroot == yroot)             return xroot;          if (xroot->rank > yroot->rank) {             yroot->parent = xroot;             return xroot;         } else {             xroot->parent = yroot;             if (xroot->rank == yroot->rank)                 yroot->rank++;             return yroot;         }     } };  int width, height;  int main() {     (int = 0; data[0][i]; i++)         width = + 1;     (int = 0; data[i]; i++) {         height = + 1;     }      std::vector<std::vector<unsigned short> > lblinfo;     lblinfo.resize(height, std::vector<unsigned short>(width, 0));      std::vector<label *> labels;     labels.push_back(null); // 0 used unassigned flag      (int y = 0; y < height; y++) {         (int x = 0; x < width; x++) {             if (data[y][x] == '1')                 continue;              // try find neighboring label             unsigned short lblid = 0;             if (x != 0 && lblinfo[y][x-1] != 0)                 lblid = lblinfo[y][x-1];              // merge cells above             if (y != 0) {                 (int x2 = x - 1; x2 <= x + 1; x2++) {                     if (x2 < 0)                         continue;                     if (x2 >= width)                         continue;                      unsigned short otherid = lblinfo[y - 1][x2];                     if (!otherid)                         continue;                      if (!lblid)                         lblid = otherid;                     else {                         labels[lblid]->merge(labels[otherid]);                     }                 }             }              if (!lblid) {                 // assign new label                 lblid = labels.size();                 labels.push_back(new label);             }             lblinfo[y][x] = lblid;         }     }      // assign indices labels set , print resulting sets     int maxindex = 0;     static const char chars[] = "abcefghijklmnopqrstuvwxyz";     (int y = 0; y < height; y++) {         (int x = 0; x < width; x++) {             unsigned short labelid = lblinfo[y][x];             if (labelid == 0) {                 putchar(data[y][x]);                 continue;             }              label *label = labels[labelid];             int idx = label->getindex(maxindex);             if (idx >= sizeof(chars) - 1) {                 printf("\n\n many labels print!\n");                 exit(1);             }              putchar(chars[idx]);         }         printf("\n");     }      return 0; } 

Comments

Popular posts from this blog

java - SNMP4J General Variable Binding Error -

windows - Python Service Installation - "Could not find PythonClass entry" -

Determine if a XmlNode is empty or null in C#? -