Java 如何降低圈复杂度?

Java 如何降低圈复杂度?,java,arrays,refactoring,minesweeper,cyclomatic-complexity,Java,Arrays,Refactoring,Minesweeper,Cyclomatic Complexity,谢谢你阅读我的问题。 我目前正在Coursera上一门Java课程,并被要求在“扫雷舰”上为作业编写一个程序。我的代码创建了正确的结果,但我的分数被大幅扣减,因为根据自动评分器的说法,我的代码“过于复杂,圈复杂度为60”。我知道有太多的条件和循环,但我很难让它变得更简单 这是我的代码。它需要3个整数命令行参数m、n和k来创建一个m-by-n网格,其中k个地雷位于随机位置。我使用“5”来标记地雷,而不是“5”,因为一个磁贴中可以得到的最大a数是4(因为一个磁贴有4条边)。如果两个地雷并排放置,可能

谢谢你阅读我的问题。 我目前正在Coursera上一门Java课程,并被要求在“扫雷舰”上为作业编写一个程序。我的代码创建了正确的结果,但我的分数被大幅扣减,因为根据自动评分器的说法,我的代码“过于复杂,圈复杂度为60”。我知道有太多的条件和循环,但我很难让它变得更简单

这是我的代码。它需要3个整数命令行参数m、n和k来创建一个m-by-n网格,其中k个地雷位于随机位置。我使用“5”来标记地雷,而不是“5”,因为一个磁贴中可以得到的最大a数是4(因为一个磁贴有4条边)。如果两个地雷并排放置,可能会在其标记“5”上添加额外的值。因此,当我打印出所有>=5的值时,我将它们变成“”。每个值由两个空格分隔

public class Minesweeper {
  public static void main(String[] args) {
    int m = Integer.parseInt(args[0]);
    int n = Integer.parseInt(args[1]);
    int k = Integer.parseInt(args[2]);
    int[][] mine = new int[m][n];
    //put the mines
    for(int z = 0; z < k; z++) {
      int randomX = (int) (Math.random() * m);
      int randomY = (int) (Math.random() * n);
      mine[randomX][randomY] = 5; 
    }

    for(int y = 0; y < n; y++) {
      for(int x = 0; x < m; x++) {
        //first row of the grid
        if(y == 0) {
          //upper left corner
          if(x == 0) {
            if(mine[x + 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y + 1] >= 5) {
              mine[x][y] += 1;
            }
          }
          //upper right corner
          else if(x == m - 1) {
            if(mine[x - 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y + 1] >= 5) {
              mine[x][y] += 1;
            } 
          }
          //mid of first row
          else {
            if(mine[x - 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x + 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y + 1] >= 5) {
              mine[x][y] += 1;
            } 
          }
        }
        //mid rows
        else if(y > 0 && y < n - 1) {
          //left side
          if(x == 0) {
            if(mine[x][y - 1] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y + 1] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x + 1][y] >= 5) {
              mine[x][y] += 1;
            }
          }
          //right side
          else if(x == m - 1) {
            if(mine[x][y - 1] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y + 1] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x - 1][y] >= 5) {
              mine[x][y] += 1;
            }
          }
          //mid
          else {
            if(mine[x][y - 1] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y + 1] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x - 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x + 1][y] >= 5) {
              mine[x][y] += 1;
            }
          } 
        }
        //bottom row
        else if(y == n - 1) {
          //bottom left corner
          if(x == 0) {
            if(mine[x + 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y - 1] >= 5) {
              mine[x][y] += 1;
            }
          }
          //bottom right corner
          else if(x == m - 1) {
            if(mine[x - 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y - 1] >= 5) {
              mine[x][y] += 1;
            }
          }
          //middle of the bottom row
          else {
            if(mine[x + 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x - 1][y] >= 5) {
              mine[x][y] += 1;
            }
            if(mine[x][y - 1] >= 5) {
              mine[x][y] += 1;
            }
          }
        }
      }
    }
  //print out the grid
    for(int y = 0; y < n; y++) {
      for(int x = 0; x < m; x++) {
        //println at the right edge of the grid
        if(x == m - 1) {
          if(mine[x][y] >= 5) {
            System.out.println("*");
          }
          else {
            System.out.println(mine[x][y]);
          }
        }
        //other tiles, no need to switch lines
        else {
          if(mine[x][y] >= 5) {
            System.out.print("*  ");
          }
          else {
            System.out.print(mine[x][y] + "  ");
          }
        }
      } 
    }
  }
}
公共级扫雷艇{
公共静态void main(字符串[]args){
int m=Integer.parseInt(args[0]);
int n=Integer.parseInt(args[1]);
intk=Integer.parseInt(args[2]);
int[]mine=新int[m][n];
//扫雷
对于(intz=0;z=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
}
}
//右上角
else如果(x==m-1){
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
} 
}
//第一排中间
否则{
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(矿[x+1][y]>=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
} 
}
}
//中排
否则如果(y>0&&y=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
}
如果(矿[x+1][y]>=5){
矿[x][y]+=1;
}
}
//右侧
else如果(x==m-1){
如果(地雷[x][y-1]>=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
}
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
}
//中段
否则{
如果(地雷[x][y-1]>=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
}
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(矿[x+1][y]>=5){
矿[x][y]+=1;
}
} 
}
//底层
else如果(y==n-1){
//左下角
如果(x==0){
如果(矿[x+1][y]>=5){
矿[x][y]+=1;
}
如果(地雷[x][y-1]>=5){
矿[x][y]+=1;
}
}
//右下角
else如果(x==m-1){
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(地雷[x][y-1]>=5){
矿[x][y]+=1;
}
}
//最底层的中间
否则{
如果(矿[x+1][y]>=5){
矿[x][y]+=1;
}
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(地雷[x][y-1]>=5){
矿[x][y]+=1;
}
}
}
}
}
//打印出网格
对于(int y=0;y=5){
System.out.println(“*”);
}
否则{
System.out.println(mine[x][y]);
}
}
//其他瓷砖,无需切换线路
否则{
如果(矿[x][y]>=5){
系统输出打印(“*”);
}
否则{
系统输出打印(mine[x][y]+“”);
}
}
} 
}
}
}

谢谢您的时间,我非常感谢您的建议。

如果您在循环中进行左/右/上/下测试以节省大量代码行,则可以降低复杂性:

for (int tryX = -1; tryX <= 1; tryX++) {
  for (int tryY = -1; tryY <= 1; tryY++) {
    if(mine[x + tryX][y + tryY] >= 5) {
      mine[x][y] += 1;
    }
  }
}

for(int-tryX=-1;tryX我不会分享重构代码,但会给你一些你应该做的想法和例子。我认为这对你的学习更有用

你应该找到相同的条件,并将它们从几个分支提取到一个分支。我建议你从内部条件开始,然后到外部条件

让我们以具有
y==0
条件的分支为例:

if(x == 0) {
  if(mine[x + 1][y] >= 5) {
     mine[x][y] += 1;
  }
  if(mine[x][y + 1] >= 5) {
    mine[x][y] += 1;
  }
}
//upper right corner
else if(x == m - 1) {
  if(mine[x - 1][y] >= 5) {
     mine[x][y] += 1;
  }
  if(mine[x][y + 1] >= 5) {
     mine[x][y] += 1;
  } 
//mid of first row
else {
  if(mine[x - 1][y] >= 5) {
    mine[x][y] += 1;
  }
  if(mine[x + 1][y] >= 5) {
    mine[x][y] += 1;
  }
  if(mine[x][y + 1] >= 5) {
    mine[x][y] += 1;
  } 
}
您可以看到,当
x==0
或在
else
分支中选中
mine[x+1][y]>=5
。您可以将两个条件合并为一个,它看起来像
x
,现在代码看起来像:

if(x < m-1 && mine[x + 1][y] >= 5) {
  mine[x][y] += 1;
}

if(x == 0) {
  if(mine[x][y + 1] >= 5) {
    mine[x][y] += 1;
  }
}
//upper right corner
else if(x == m - 1) {
  if(mine[x - 1][y] >= 5) {
     mine[x][y] += 1;
  }
  if(mine[x][y + 1] >= 5) {
     mine[x][y] += 1;
  } 
//mid of first row
else {
  if(mine[x - 1][y] >= 5) {
    mine[x][y] += 1;
  }
  if(mine[x][y + 1] >= 5) {
    mine[x][y] += 1;
  } 
}
if(x=5){
矿[x][y]+=1;
}
如果(x==0){
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
}
}
//右上角
else如果(x==m-1){
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(矿[x][y+1]>=5){
矿[x][y]+=1;
} 
//第一排中间
否则{
如果(地雷[x-1][y]>=5){
矿[x][y]+=1;
}
如果(我的)