模式识别:连续四个相同数字(二维数组)

2017-10-10  本文已影响0人  五秋木

1. 题目:

测试一个二维数组是否存在四个连续的数字具有相同的数值,在水平方向、垂直方向和正反对角线方向判断。
函数:public static boolean isConsecutiveFour(int [][] values)
编写一个测试程序,提示用户输入一个二维数组的行数,列数以及矩阵,若存在四个连续相同的数字就显示true,否则,false。
测试用例:

用例1
0 1 0 3 1 6 1
0 1 6 8 6 0 1
5 6 2 1 8 2 9
6 5 6 1 1 9 1
1 3 6 1 4 0 7
3 3 3 3 4 0 7

用例2
0 1 0 3 1 6 1
0 1 6 8 6 0 1
5 5 2 1 8 2 9
6 5 6 1 1 9 1
1 5 6 1 4 0 7
3 5 3 3 4 0 7

用例3
0 1 0 3 1 6 1
0 1 6 8 6 0 1
5 6 2 1 6 2 9
6 5 6 6 1 9 1
1 3 6 1 4 0 7
3 6 3 3 4 0 7

用例4
0 1 0 3 1 6 1
0 1 6 8 6 0 1
9 6 2 1 8 2 9
6 9 6 1 1 9 1
1 3 9 1 4 0 7
3 5 3 9 4 0 7

2. 方法一

依次按照行、列、反对角线、正斜对角线
其中对行处理代码如下:

public static boolean isRowConsecutiveFour(int [][]values)
    {
        //row
        int count;
        for(int i=0;i<values.length;i++)
        {
            count=1;
            for(int j=1;j<values[i].length;j++)
            {
                if(values[i][j]==values[i][j-1])
                    count++;
                else
                    count=1;
                if(count==4)
                    return true;
            }
        }
        return false;
    }

于是列的处理就变成把矩阵转置之后直接对行处理即可
对于反斜对角线的处理:


2.png

从行+列的和开始,和为3的直线正好是左上角的第一组反斜线,下面的斜线和以此加1,直到和为row+column-2-3为止,先计算和从3到column-1的所有斜线,并且要确保数组访问不越界,后面接着计算和从column到
row+column-2-3的所有斜线。
代码如下:

public static boolean isTriConsecutiveFour(int [][]values)
    {
        int count;
        for (int k = 3; k < values[0].length; k++) {
            count = 1;
            for (int i = 1; i <= k && i < values.length; i++) {
                int j = k - i;
                if (values[i][j] == values[i - 1][j + 1])
                    count++;
                else
                    count = 1;
                if (count == 4)
                    return true;
            }
        }
        for (int k = values[0].length; k <=values[0].length+values.length-5; k++) {
            count = 1;
            for (int j=values[0].length-2; j <= k && j >= 0; j--) {
                int i = k - j;
                if(i==values.length)
                    break;
                if (values[i][j] == values[i - 1][j + 1])
                    count++;
                else
                    count = 1;
                if (count == 4)
                    return true;
            }
        }
        return false;
    }

最后对于正斜线的处理,直接将原始矩阵中元素左右互换,直接使用对反斜线处理的方法即可。

3. 方法二

对每一个元素从向右,向下,向右下,向右上以此遍历,例如从向右搜索,找该元素右边的三个元素,先判断最后一个是否越界,若越界,则向右遍历失败。若不越界,开始判断是否存在四个元素中有不相同的,若存在,则向右遍历失败。开始向下、向右下、向右上遍历。
另外将方向存到一个4*2的数组中,如下:

int [][] direction = {
                {0,1},
                {1,0},
                {1,1},
                {-1,1}
        };

判断越界函数如下:

  public static boolean isOverflowEdge(int i,int row,int j,int column)
  {
      if(i<0||i>=row||j<0||j>=column)
          return true;
      return false;
  }

向某个方向(右,下,右下,右上)遍历如下:toDirection就是方向数组direction中的某一行

public static boolean TraversalDirection(int [][]values, int i,int row,int j,int column,int[] toDirection)
  {
        boolean flag = true;
        //if(!isOverflowEdge(i-3,row,j,column))//无需向上 向左 向左上 向左下 还剩下四个方向
        //向右 向下 向右下 向右上 判断是否出界
        if(!isOverflowEdge(i+3*toDirection[0],row,j+3*toDirection[1],column))  
            {
                for(int k=0;k<3;k++)
                    {
                        if(values[i+k*toDirection[0]][j+k*toDirection[1]]!=values[i+(k+1)*toDirection[0]][j+(k+1)*toDirection[1]])
                            {
                                flag=false;
                                break;
                            }
                    }
            }
        else
            flag=false;
        return flag;
  }
上一篇 下一篇

猜你喜欢

热点阅读