1、题目:一个数据矩阵,选定某个位置的数据元作为参考,寻找与该数据元值相同的连成一片的最大范围。如下二维数组中所示,选择arr[1][3]作为参考对象,从位置(1,3)开始寻找所有相连的值为‘1’的元素。结果很明显如下图1所示。
int arr[5][5]={ 1,0,1,0,0, 0,1,1,1,0, 0,1,0,1,1, 0,1,0,0,1, 0,1,1,1,1 };
图1:
2、深度遍历方法
从(1,3)位置开始,按照“上、右、下、左”的顺序检查相邻位置的值是否与参考值相同,如果相同则被筛选到候选集中,并以该点为基点再出发扩展检查。
a. (1,3)-->(2,3)-->(2,4)-->(3,4)-->(4,4)-->(4,3)-->(4,2)-->(4,1)-->(3,1)-->(2,1)-->(1,1)-->(1,2)-->{ (1,3) || (0,2) }
b. (1,3)-->(1,2)-->...
深度遍历可能从不同的路径到达相同的位置点,正如上面的(1,2)位置。为了避免形成回路,还得记住已识别点的位置。从分析来看,计算过程比较复杂,要记住所有点位置,也需要不少的内存空间;计算上,每识别一个新点,都要在已检测集合中进行匹配。
3、广度遍历方法
从(1,3)位置开始,按照“上、右、下、左”的顺序检查相邻位置的值是否与参考值相同,如果相同则被筛选到候选集合中,并作为新的参考点。
(1,3)-->(2,3)-->(1,2)
|-->(2,4) |-->(0,2)
...
如此,从(1,3)位置相邻4个点筛选,命中的点追加的候选队列中。为了避免回路,把每个点4个相邻方向的检查状态记录下来,0表示未检测,1表示已检测为有相同值,2表示检测为无相同值(边界点)。这些信息在后续的检测中,避免重复循环。
#include <iostream> #include <queue> #include <vector> using namespace std; struct nposition { int x, y; //position in 2D array char statN, statE, statS, statW; //north, east, south, west: 0-uncheck, 1-checked, 2-edge }; #define MAX_LIMIT 5 int main() { int arr[5][5]={ 1,0,1,0,0, 0,1,1,1,0, 0,1,0,1,1, 0,1,0,0,1, 0,1,1,1,1 }; queue<nposition> active; //待检测队列 vector<nposition> checked; //已检测的点 nposition seed={0}; int val=1; seed.x = 1; seed.y = 3; active.push( seed ); while( !active.empty() ) { nposition p=active.front(); if( p.statN == 0 ) { if( p.x > 0 && arr[p.x-1][p.y] == val ) { nposition temp = {0}; temp.x = p.x-1; temp.y = p.y; temp.statS = 1; active.push( temp ); p.statN = 1; } else p.statN = 2; } if( p.statE == 0 ) { if( p.y < MAX_LIMIT-1 && arr[p.x][p.y+1] == val ) { nposition temp = {0}; temp.x = p.x; temp.y = p.y+1; temp.statW = 1; active.push( temp ); p.statE = 1; } else p.statE = 2; } if( p.statS == 0 ) { if( p.x < MAX_LIMIT-1 && arr[p.x+1][p.y] == val ) { nposition temp = {0}; temp.x = p.x+1; temp.y = p.y; temp.statN = 1; active.push( temp ); p.statS = 1; } else p.statS = 2; } if( p.statW == 0 ) { if( p.y > 0 && arr[p.x][p.y-1] == val ) { nposition temp = {0}; temp.x = p.x; temp.y = p.y-1; temp.statE = 1; active.push( temp ); p.statW = 1; } else p.statW = 2; } active.pop(); checked.push_back( p ); }//!while // int i=0; cout<<"linked positions:"<<endl; for( ; i<checked.size(); ++i ) { cout<<" ("<<checked[i].x<<","<<checked[i].y<<")"<<endl; } }