日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

寻找连通域

發(fā)布時(shí)間:2024/9/30 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 寻找连通域 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.mrluoyi.com/blog/2012/03/connected-domain/#respond

尋找一副二值圖像中的連通域。全圖遍歷+DFS深度優(yōu)先搜索。

示例輸入: 5 5 0 0 0 0 1 0 1 1 0 1 0 1 0 0 1 1 1 1 0 1 1 1 0 0 1 示例輸出: The number of connected domains is: 2 Connected domains are labeled as below: 0 0 0 0 2 0 3 3 0 2 0 3 0 0 2 3 3 3 0 2 3 3 0 0 2

第一種辦法比較直觀,是遞歸的辦法,代碼如下:

#include<stdio.h>//by Yi Luo (03/08/2012)#define max 500 int I[max][max]; int n, m;// size = n*m int num = 0;const int direction[][2]={{1,0},{0,-1},{0,1},{-1,0}};bool check(int x, int y){if (x >= 0 && x < n && y >= 0 && y < m && I[x][y] == 1){return true;}else{return false;} }bool DFS(int x, int y, int label){if (1 != I[x][y]) {return false;}else{I[x][y] = label;for (int i = 0; i < 4; i++){if (check(x + direction[i][0], y + direction[i][1])){DFS(x + direction[i][0], y + direction[i][1], label);}} }return true; }int main(void) {scanf("%d%d", &n, &m);for (int i = 0; i < n; ++i){for (int j=0; j< m; j++){scanf("%d", &I[i][j]);} }int label = 2; for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){if (DFS(i, j, label)){label++;}}}num = label - 2;printf("\n\nThe number of connected domains is: %d\n", num);printf("Connected domains are labeled as below:\n\n");for (int i = 0; i < n; ++i){for (int j=0; j< m; j++){printf("%d ", I[i][j]);} printf("\n");}getchar();getchar();return 0; }

剛剛又學(xué)到了一種新的辦法,就是直接掃描的辦法,比較巧妙。對(duì)于四領(lǐng)域的情況,主要是考察每個(gè)前景點(diǎn)的左邊、上邊兩個(gè)點(diǎn)的情況:

1、如果左邊和上邊都有標(biāo)記過的前景點(diǎn),則選擇二者標(biāo)號(hào)更小的作為當(dāng)前點(diǎn)的標(biāo)記,并將之前所有的大號(hào)改成小號(hào);
2、如果只有左邊是標(biāo)記過的點(diǎn),則將當(dāng)前點(diǎn)和其左邊點(diǎn)標(biāo)號(hào)一致;
3、如果只有上邊是標(biāo)記過的點(diǎn),則和上面的點(diǎn)標(biāo)號(hào)一致;
4、如果左邊和上邊都沒有標(biāo)記過的點(diǎn),則當(dāng)前前景點(diǎn)新開一個(gè)標(biāo)號(hào)。

代碼如下:



#include<stdio.h>//by Yi Luo (03/09/2012)#define size 500 int I[size][size];//二值圖像矩陣 int n, m, min, max;// size = n*m int num = 0;//連通域數(shù)目 bool check(int x, int y){if (x >= 0 && x <= n && y >= 0 && y <= m && I[x][y] != 0){return true;}else{return false;} }int main(void) {scanf("%d%d", &n, &m);for (int i = 0; i < n; ++i){for (int j=0; j< m; j++){scanf("%d", &I[i][j]);} //讀入二值圖像矩陣}int label = 1;for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){if (check(i, j))//如果當(dāng)前位置是合法前景 {if (check(i, j-1)) {if (check(i-1, j))//如果該點(diǎn)的左面、上面均是標(biāo)注過的前景{min = I[i-1][j];max = I[i][j-1];if (max < min) { min = I[i][j-1]; max = I[i-1][j];for (int t = j; t >= 0; t--){for (int w = i; w >=0; w--){if (I[w][t] == max) { I[w][t] = min; }}}label--;}I[i][j] = min;} else //如果只有該點(diǎn)的左面是標(biāo)注過的前景{I[i][j] = I[i][j-1];}} else if (check(i-1, j)) //如果只有該點(diǎn)的上面是標(biāo)注過的前景{I[i][j] = I[i-1][j];} else //如果該點(diǎn)的左面,上面都不是標(biāo)注過的前景{label ++;I[i][j] = label;}}}}num = label - 1;printf("\n\nThe number of connected domains is: %d\n", num);printf("Connected domains are labeled as below:\n\n");for (int i = 0; i < n; ++i){for (int j=0; j< m; j++){printf("%d ", I[i][j]);} //輸出新的標(biāo)注結(jié)果 printf("\n");}getchar();getchar();return 0; }



總結(jié)

以上是生活随笔為你收集整理的寻找连通域的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。