用于在矩阵中搜索模式的算法或java代码

时间:2015-12-30 06:29:25

标签: java algorithm matrix

我有一个像下面那样的4 * 5矩阵。

1 1 1 0 0
1 0 0 0 1
1 1 1 0 0
0 0 0 1 1

我正在寻找java中的程序来获取以下组的模式。

  • 一组后续的5 1。
  • 一组后续的2 1。
  • 2组单身1。

上述任何一组都不应相交。 这是Zycus infotech的一个面试问题,我无法解决。任何能够提出解决这个问题的逻辑的人都会很有帮助!

1 个答案:

答案 0 :(得分:2)

我将假设对数据的处理和组织方式没有限制。通过这个我的意思是你没有必要用给定的矩阵就地做任何事情,并且你可以创建辅助数据结构来帮助你完成任务(因为我在我的答案中使用了一个额外的ArrayList)。

我们从:

开始
int[][] matrix = {{1,1,1,0,0},{1,0,0,0,1},{1,1,1,0,0},{0,0,0,1,1}};

对应我们原来的结构:

1 1 1 0 0
1 0 0 0 1
1 1 1 0 0
0 0 0 1 1

所以,我们马上看到,为了获得一组4个1,我们需要从第2行到第3行,然后得到一个5个1的组,我们需要从第4行回来这意味着我们基本上将这个矩阵视为1和0的连续线,并且矩阵结构使这一点令人困惑。因此,我们可以将其扁平化以使事情变得更容易:

    List<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            list.add(matrix[i][j]);
        }
    }

这给了我们:

[1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1]

这看起来好一点了!但是,我们仍然有这个列表的问题在一个循环中包围自己。现在,我们可以编写代码来解释这个列表本身仍然可能相邻的1,或者我们可以修改列表,以便我们知道100%肯定在列表的开头和结尾之间没有相邻的1。这意味着我们希望列表以0开头或结尾,从而确保没有邻接。我们通过从列表开头到列表末尾的所有1的一个很好的小移动来实现这一点。

    // keep track of how we're adjusting the list so we can calculate the proper start of adjacency
    int adjustment = 0;
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i) == 1) {
            list.add(list.remove(i));
            i--;
            adjustment++;
        } else {
            break;
        }
    }

现在我们有:

[0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

我们现在可以很容易地根据要求获得所需的1组。

如果你只是想计算1的邻接:

    int count = 0;
    for (Integer a : list) {
        if (a == 1) {
            count++;
        } else {
            if (count > 0) {
                System.out.println("Group of " + count + " adjacent 1's");
            }
            count = 0;
        }
    }
    if (count > 0) {
        System.out.println("Group of " + count + " adjacent 1's");
    }

如果您正在寻找1组5个相邻的1个,2个相邻的1个组和1个1个相邻1组没有交叉点,那么我们可以这样做:

    for (int num : Arrays.asList(5, 2, 2, 1)) {
        int count = 0;
        int start = -1;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1) {
                if (start == -1) {
                    start = i;
                }
                count++;
            } else {
                start = -1;
                count = 0;
            }
            if (count == num) {
                System.out.println("Group of " + num + " adjacent 1's starting at " + ((start + adjustment) / 5) + "," + ((start + adjustment) % 5));
                for (int j = start; j < start + count; j++) {
                    list.set(j, 0);
                }
                break;
            }
        }
    }

通过查看计数相邻的列表来工作,直到我们达到我们想要的数量(从我们的最大数字(5)开始并逐渐减小),然后我们输出它的开始,然后去掉那些相邻的列表中的1(通过将它们设置为0)。这样,我们就不会意外地再次计算它们(满足我们对没有交叉群的限制)。一旦我们得到了相邻1的所需数量,我们也存储了它的起始位置。然后我们根据从列表开头到后面移动了多少1来调整它,然后除以得到行号并使用模数来获得列号。

我们的结果是:

Group of 5 adjacent 1's starting at 3,3
Group of 2 adjacent 1's starting at 1,4
Group of 2 adjacent 1's starting at 2,1
Group of 1 adjacent 1's starting at 1,0

到目前为止,我已假设矩阵中始终至少有一个0。如果没有,您需要在我的循环之前添加list.contains(0)检查,以便将1从列表的前面移动到列表的后面。

将这些全部放在一个代码块中:

    int[][] matrix = {{1,1,1,0,0},{1,0,0,0,1},{1,1,1,0,0},{0,0,0,1,1}};
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            list.add(matrix[i][j]);
        }
    }

    int adjustment = 0;
    if (list.contains(0)) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1) {
                list.add(list.remove(i));
                i--;
                adjustment++;
            } else {
                break;
            }
        }
    }

    int count = 0;
    for (Integer a : list) {
        if (a == 1) {
            count++;
        } else {
            if (count > 0) {
                System.out.println("Group of " + count + " adjacent 1's");
            }
            count = 0;
        }
    }
    if (count > 0) {
        System.out.println("Group of " + count + " adjacent 1's");
    }

    for (int num : Arrays.asList(5, 2, 2, 1)) {
        int count2 = 0;
        int start = -1;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1) {
                if (start == -1) {
                    start = i;
                }
                count2++;
            } else {
                start = -1;
                count2 = 0;
            }
            if (count2 == num) {
                System.out.println("Group of " + num + " adjacent 1's starting at " + ((start + adjustment) / 5) + "," + ((start + adjustment) % 5));
                for (int j = start; j < start + count2; j++) {
                    list.set(j, 0);
                }
                break;
            }
        }
    }