zoukankan      html  css  js  c++  java
  • 边界检测算法分析与实现

    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;
        }
    }
  • 相关阅读:
    xna 添加一个精灵1
    【leetcode】705. 设计哈希集合
    【leetcode】1603. 设计停车系统
    【leetcode】设计有序流
    【leetcode】旅行终点站
    【leetcode】检测大写字母
    【leetcode】重复至少 K 次且长度为 M 的模式
    【leetcode】二叉树的直径
    【leetcode】公交站间的距离
    【leetcode】分糖果
  • 原文地址:https://www.cnblogs.com/feika/p/3574216.html
Copyright © 2011-2022 走看看