前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >递归查找矩阵连通域

递归查找矩阵连通域

作者头像
零式的天空
发布2022-03-22 10:54:15
4580
发布2022-03-22 10:54:15
举报
文章被收录于专栏:零域Blog

题目的来源是给定一张图片,查找所有临近的像素点,并求出最大像素值。经过抽象后是:两个矩阵,一个只是包含0 1,另一个是每个位置具体的像素值,可以通过查找第一个矩阵来确定连通域的点,根据第二个矩阵得出最大的值。

矩阵1:

代码语言:javascript
复制
# data
1 0 0 0 1 0 0 0 0 1
0 1 0 0 1 0 0 0 0 0
0 1 1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 1
1 0 0 0 1 0 0 0 0 1
0 1 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 1 0 0 1 0 0 0 0 0

矩阵2:

代码语言:javascript
复制
# data2
1 0 0 0 1 0 0 0 0 1
0 2 0 0 3 0 0 0 0 0
0 1 1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 4 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 5 1 1 0
0 0 0 0 0 0 0 0 0 1
1 0 0 0 1 0 0 0 0 1
0 6 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 7 0 0 8 0 0 0 0 0

C++代码为:

代码语言:javascript
复制
// recursionFindPoints.cpp

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef double    db;

long flag = 2;
long START = flag;

int recursion(ll i, ll j, vector<vector<ll> > &data, vector<pair<ll,ll> > &position);
int launch( vector<vector<ll> > &data, vector<vector<db> > &data2);

int main(int argc, char * argv[])
{
    if (argc != 3)
    {
        cout<<"Enter two file"<<endl;
        return -1;
    }
    // 1 read map and intensity
    ifstream fin(argv[1]);
    ifstream fin2(argv[2]);

    vector<vector<ll> > data;
    vector<vector<db> > data2;
    vector<ll> temp;
    ll v;
    vector<db> temp2;
    db d;

    string line;
    string value;
    while (getline(fin,line))
    {
        stringstream ss(line);
        while (getline(ss,value,' '))
        {
           v = atoi(value.c_str());  
           temp.push_back(v);
        }
        data.push_back(temp);
        temp.clear();
    }	

    while (getline(fin2,line))
    {
        stringstream ss(line);
        while (getline(ss,value,' '))
        {
           d = atoi(value.c_str());  
           temp2.push_back(d);
        }
        data2.push_back(temp2);
        temp2.clear();
    }	

    // 2 entrance
    launch(data,data2);

    // 3 output result
    for (vector<vector<ll> >::iterator it = data.begin(); it != data.end(); ++it)
    {
        for (vector<ll>::iterator i = (*it).begin(); i != (*it).end(); ++i)
            cout<<*i<<" ";
        cout<<endl;
    }

}

int launch(vector<vector<ll> > &data, vector<vector<db> > &data2)
{
    // 1. Find all points in connected domain and store these coordinate
    vector<vector<pair<ll,ll> > > result;
    vector<pair<ll,ll> >  temp;
    for (int i = 0; i < data.size(); ++i)
    {
        for (int j = 0; j < data[0].size(); ++j)
        {
            if (data[i][j] == 1)
            {
               temp.push_back(make_pair(i,j)); 
               data[i][j] = flag;
               recursion(i,j,data,temp);
               flag++;
               result.push_back(temp);
               temp.clear();
            }
        }
    }

    // 2. Filter
    pair<ll,ll> pos;
    db inten = 0;
    for (vector<vector<pair<ll,ll> > >::iterator it = result.begin(); it != result.end(); ++it)
    {
        for (vector<pair<ll, ll> >::iterator jt = (*it).begin(); jt != (*it).end(); ++jt)
        {
            // cout<<(*jt).first<<" "<<(*jt).second<<"    ";
            if (inten <= data2[(*jt).first][(*jt).second])
            {
                inten = data2[(*jt).first][(*jt).second];
                pos.first = (*jt).first;
                pos.second = (*jt).second;
            }
        }
        // cout<<endl;
        printf("The %d points's max intensity is: %d\n", int(START), int(inten));
        START ++;
        inten = 0;
    }

    return 0;
}

int recursion(ll i, ll j, vector<vector<ll> > &data, vector<pair<ll,ll> > &position)
{
    for (int x = i - 1; x <= i + 1; x++)
    {
        for (int y = j - 1; y <= j + 1; y++)
        {
            if (x == i && y == j)
                continue;
            if (x >= 0 && x < data.size() && y >= 0 && y < data[0].size() && data[x][y] == 1)
            {
                position.push_back(make_pair(x, y));
                data[x][y] = flag;
                recursion(x,y,data,position);
            }
        }
    }
    return 0;
}

运行程序及结果:

代码语言:javascript
复制
$ g++ recursionFindPoints.cpp -o rfp
$ ./rfp data data2
The 2 points's max intensity is: 2
The 3 points's max intensity is: 3
The 4 points's max intensity is: 1
The 5 points's max intensity is: 1
The 6 points's max intensity is: 4
The 7 points's max intensity is: 1
The 8 points's max intensity is: 5
The 9 points's max intensity is: 6
The 10 points's max intensity is: 1
The 11 points's max intensity is: 1
The 12 points's max intensity is: 7
The 13 points's max intensity is: 8
2 0 0 0 3 0 0 0 0 4 
0 2 0 0 3 0 0 0 0 0 
0 2 2 0 3 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 5 
0 0 0 0 6 0 0 0 0 0 
0 0 0 6 0 0 0 0 0 0 
7 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 8 8 0 0 0 
0 0 0 0 0 0 8 8 8 0 
0 0 0 0 0 0 0 0 0 8 
9 0 0 0 10 0 0 0 0 8 
0 9 0 0 10 0 0 0 0 0 
0 0 0 0 0 0 0 11 0 0 
0 12 0 0 13 0 0 0 0 0

运行结果分两部分,第一部分是找到的每个连通域中点的最大值,第二部分是在第一个矩阵的基础上对连通域进行标号区分之后的矩阵

程序使用递归来查找一个九宫格的中心对周围八个点的关系,几行代码即可实现,可见递归的精妙,缺点是递归有最大层数,如果超过了会导致堆栈溢出,所以不能应用于太大的矩阵

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-04-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档