You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计二维数组中的岛屿与大陆?技术实现问询

解决二维数组中岛屿与大陆的计数问题

首先我们先明确问题中的定义,避免歧义:

  • 陆地:数组中值为1的单元格
  • 邻居:仅指共边相邻的单元格(即上下左右四个方向,不包含对角线)
  • 岛屿:没有任何邻居的陆地(也就是上下左右全为0的单个1)
  • 大陆:由两个及以上相邻陆地组成的连通区域(连通块大小≥2的陆地区域)
  • 我们需要统计的是:岛屿的数量 + 大陆连通区域的数量

针对你提供的不完整代码,我会完善并扩展出完整的计数逻辑,帮你实现需求:

实现思路

  1. 遍历二维数组的每个单元格
  2. 当遇到未被访问过的陆地(1)时:
    • 用深度优先搜索(DFS)探索整个连通块,统计块的大小
    • 根据连通块的情况判断是岛屿还是大陆:
      • 如果连通块大小为1,且该陆地无邻居 → 计数+1(岛屿)
      • 如果连通块大小≥2 → 计数+1(大陆)
  3. 使用访问标记数组避免重复统计同一个连通块

完整代码实现

#include <stdio.h>
#include <stdbool.h>

// 定义数组的固定维度
#define SIZE 8

// 计算单个陆地的邻居数量
int count_neighbors(const int array[][SIZE], int i, int x) {
    int neighbors = 0;
    // 检查上方单元格
    if (i > 0 && array[i-1][x] == 1) neighbors++;
    // 检查下方单元格
    if (i < SIZE-1 && array[i+1][x] == 1) neighbors++;
    // 检查左方单元格
    if (x > 0 && array[i][x-1] == 1) neighbors++;
    // 检查右方单元格
    if (x < SIZE-1 && array[i][x+1] == 1) neighbors++;
    return neighbors;
}

// 深度优先遍历,统计连通块的大小
int dfs(const int array[][SIZE], bool visited[][SIZE], int i, int x) {
    // 越界、已访问、不是陆地,直接返回0
    if (i < 0 || i >= SIZE || x < 0 || x >= SIZE || visited[i][x] || array[i][x] != 1) {
        return 0;
    }
    // 标记当前单元格为已访问
    visited[i][x] = true;
    // 递归遍历四个方向,累加连通块的总大小
    return 1 + dfs(array, visited, i-1, x) + dfs(array, visited, i+1, x) +
           dfs(array, visited, i, x-1) + dfs(array, visited, i, x+1);
}

// 统计岛屿与大陆的总数
int count_islands_and_continents(const int array[][SIZE]) {
    int total = 0;
    // 初始化访问标记数组,默认全为未访问
    bool visited[SIZE][SIZE] = {false};
    
    for (int i = 0; i < SIZE; i++) {
        for (int x = 0; x < SIZE; x++) {
            // 遇到未访问的陆地单元格
            if (array[i][x] == 1 && !visited[i][x]) {
                int block_size = dfs(array, visited, i, x);
                if (block_size == 1) {
                    // 检查是否是孤立岛屿(无邻居)
                    if (count_neighbors(array, i, x) == 0) {
                        total++;
                    }
                } else {
                    // 连通块大小≥2,属于大陆
                    total++;
                }
            }
        }
    }
    return total;
}

// 测试示例
int main() {
    int test_array[SIZE][SIZE] = {
        {1, 0, 0, 0, 0, 0, 0, 1},
        {1, 1, 0, 0, 0, 1, 1, 1},
        {0, 0, 0, 0, 0, 1, 0, 0},
        {0, 0, 1, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 1, 1, 1, 0, 0, 1, 0},
        {0, 1, 0, 1, 0, 0, 1, 0},
        {0, 1, 1, 1, 0, 0, 1, 0}
    };
    
    int result = count_islands_and_continents(test_array);
    printf("岛屿与大陆总数:%d\n", result);
    // 预期结果:5(2个大陆连通块 + 1个孤立岛屿 + 2个大陆连通块)
    return 0;
}

代码说明

  • count_neighbors:专门用来判断单个陆地是否为孤立岛屿,通过统计上下左右四个方向的邻居数量实现
  • dfs:深度优先搜索是处理连通块问题的常用方法,这里用来遍历整个陆地连通块,统计大小并标记已访问单元格,避免重复处理
  • count_islands_and_continents:主逻辑函数,遍历数组的每个单元格,对每个未处理的陆地块进行判断,累加总数

如果你对“大陆”的定义有不同理解(比如认为单个陆地有≥2个邻居就算大陆,而非连通块),可以调整判断逻辑:直接遍历每个陆地单元格,统计邻居数,邻居数为0则岛屿计数+1,邻居数≥2则大陆计数+1,最后总和两者即可。不过通常这类问题都是以连通块为单位统计,所以上面的实现更符合常规场景。

内容的提问来源于stack exchange,提问作者Ivaylo Hristov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:04:45