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

C语言疫情邻域矩阵边缘情况判断代码的简化问询

问题描述

我有一个代表疫情社区的方形矩阵,每个单元格对应一户住宅,住宅有三种状态:S(患病)、H(痊愈)、C(传染期)。输入天数后,需要按以下规则每日更新社区状态:

  • 若住宅状态为H,且上下左右(非对角线)邻域存在C,则转为C;
  • 若住宅状态为C,且8个方向(含对角线)的邻域中至少有2个C,则转为S;
  • 若住宅状态为S,则转为H。

我已经实现了判断C类住宅边缘情况的limit_C函数,代码如下:

void limit_C(char **neigh, int i, int j, int d, char **help)
{
    int counter = 0;

    if ((i == 0) && (j == 0))
   {
       if(help[i + 1][j] == CONTAGIOUS)
       {counter++;}
           
          if(help[i][j + 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j + 1] == CONTAGIOUS)
          {counter++;}
       
           if(counter >= 2)
           {neigh[i][j] = SICK;}
       
   }
   else if ((i == d - 1) && (j == d - 1))
   {
         if(help[i - 1][j] == CONTAGIOUS)
        {counter++;}
       
         if(help[i][j - 1] == CONTAGIOUS)
         {counter++;}
       
         if(help[i - 1][j - 1] == CONTAGIOUS)
        {counter++;}
       
       if(counter >= 2)
            {neigh[i][j] = SICK;}
   }
       
   else if ((i == d - 1) && (j == 0))
   {
          if(help[i - 1][j] == CONTAGIOUS)
          {counter++;}
       
          if(help[i][j + 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i - 1][j + 1] == CONTAGIOUS)
          {counter++;}
       
       if(counter >= 2)
            {neigh[i][j] = SICK;}
   }
   else if ((i == 0) && (j == d - 1))
   {
          if(help[i + 1][j] == CONTAGIOUS)
          {counter++;}
       
          if(help[i][j - 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j - 1] == CONTAGIOUS)
          {counter++;}
       
       if(counter >= 2)
            {neigh[i][j] = SICK;}
       
   }
   
  else if((i == 0) && (j != 0))
   {
          if(help[i][j + 1] == CONTAGIOUS)
          {counter++;}
           
          if(help[i][j - 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j + 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j - 1] == CONTAGIOUS)
          {counter++;}
       
       if(counter >= 2)
       {neigh[i][j] = SICK;}
       
   }
   
   else if ((i != 0) && (j == 0))
   {
          if(help[i][j + 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i - 1][j] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j] == CONTAGIOUS)
          {counter++;}
       
          if(help[i - 1][j + 1] == CONTAGIOUS)
          {counter++;}
       
          if(help[i + 1][j + 1] == CONTAGIOUS)
          {counter++;}
       
       if(counter >= 2)
       {neigh[i][j] = SICK;}
       
   }
    else if((i == d - 1) && (j != d - 1))
    {
        if(help[i - 1][j] == CONTAGIOUS)
        {counter++;}
        
        if(help[i][j + 1] == CONTAGIOUS)
        {counter++;}
        
        if(help[i][j - 1] == CONTAGIOUS)
        {counter++;}
        
        if(help[i - 1][j + 1] == CONTAGIOUS)
        {counter++;}
        
        if(help[i - 1][j - 1] == CONTAGIOUS)
        {counter++;}
        
        if(counter >= 2)
        {neigh[i][j] = SICK;}
        
        
    }
    
    else if((i != d - 1) && (j == d - 1))
    {
        if(help[i - 1][j] == CONTAGIOUS)
        {counter++;}
        
        if(help[i + 1][j] == CONTAGIOUS)
        {counter++;}
        
        if(help[i][j - 1] == CONTAGIOUS)
        {counter++;}
        
        if(help[i - 1][j - 1] == CONTAGIOUS)
        {counter++;}
        
        if(help[i + 1][j - 1] == CONTAGIOUS)
        {counter++;}
        
        if(counter >= 2)
        {neigh[i][j] = SICK;}
        
    }
}

请问有没有更简洁的写法实现这个函数的功能?


优化方案

有更简洁的写法,核心思路是用循环遍历8个方向的偏移量,同时判断每个偏移后的坐标是否在矩阵范围内,彻底避免大量重复的条件分支。

优化后的代码如下:

// 定义8个方向的坐标偏移量,覆盖所有邻域方向
static const int dirs[8][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}, {-1,-1}, {-1,1}, {1,-1}, {1,1}};

void limit_C(char **neigh, int i, int j, int d, char **help)
{
    int counter = 0;
    // 遍历所有8个邻域方向
    for (int k = 0; k < 8; k++) {
        int ni = i + dirs[k][0];
        int nj = j + dirs[k][1];
        // 检查坐标是否在矩阵有效边界内
        if (ni >= 0 && ni < d && nj >= 0 && nj < d) {
            if (help[ni][nj] == CONTAGIOUS) {
                counter++;
            }
        }
    }
    // 满足条件则转换状态
    if (counter >= 2) {
        neigh[i][j] = SICK;
    }
}

优化说明

  1. 消除冗余分支:原代码针对角落、边缘、中心位置分别写判断逻辑,重复代码多。优化后用统一的循环和边界检查,一次性覆盖所有位置的情况,逻辑更紧凑。
  2. 扩展性更强:如果后续需要调整邻域方向(比如增减方向),只需修改dirs数组即可,无需改动大量条件判断。
  3. 可读性更高:代码逻辑清晰,一眼就能看出是遍历所有邻域并计数,维护成本大幅降低。
  4. 功能完全等价:新代码的计数逻辑和原代码完全一致,只是实现方式更高效简洁,不会改变原有功能。

内容的提问来源于stack exchange,提问作者The Bulletbroof Joker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:57:02