递归检查模式

时间:2011-02-10 05:54:26

标签: python algorithm recursion

*注意我将东西称为矩阵但不是,它只是1和0的集合

假设您的矩阵始终为正方形(n x n)。是否可以确定是否存在单个列/行/对角线,以使每个项目为1。

以下面的矩阵为例(True):

1 0 0
1 1 0
0 0 1

另一个例子(True):

1 1 1
0 0 0
0 1 0

最后一个没有解决方案(假):

0 1 1
1 0 0
0 0 0

注意对角线是如何填充1的。规则是存在解决方案或没有解决方案。矩阵中可以有任意数量的1或0。我真正需要做的就是,如果你有(n x n)那么应该有一个行/列/对角线,其中n个元素是相同的。

如果递归无法做到这一点,请告诉我什么是最好和最有效的方法。非常感谢,我已经坚持了几个小时,所以任何帮助都是值得赞赏的(如果你能发布那些很棒的样品)。

修改
这是我提出的一个解决方案,但一段时间后它变得非常复杂。

拿我给的第一个例子,将所有行串起来,得到:

1 0 0,1 1 0,0 0 1
然后在行之间添加零以获得:
1 0 0 0,1 1 0 0,0 0 1 0

现在,如果你仔细观察,你会发现形成解决方案的1之间的距离是相等的。我不知道如何实现这一点。

3 个答案:

答案 0 :(得分:2)

为了寻找一个优雅的解决方案,我想出了这个:

class LineOfOnesChecker(object):

    _DIAG_INDICES = (lambda i: i, lambda i: -i - 1)

    def __init__(self, matrix):
        self._matrix = matrix
        self._len_range = range(len(self._matrix))

    def has_any(self):
        return self.has_row() or self.has_col() or self.has_diag()

    def has_row(self):
        return any(all(elem == 1 for elem in row)
                   for row in self._matrix)

    def has_col(self):
        return any(all(self._matrix[i][j] == 1 for i in self._len_range)
                   for j in self._len_range)

    def has_diag(self):
        return any(all(self._matrix[transf(i)][i] == 1 for i in self._len_range)
                   for transf in self._DIAG_INDICES)

用法:

print LineOfOnesChecker(matrix).has_any()

答案 1 :(得分:0)

您可以列出 n 1 ,并为对角线元素,行元素和列元素以及其中任何一个执行'AND' AND操作结果为TRUE,然后您就拥有了有效的模式。

import sys
matrix = [[1,0,1],[1,0,1],[1,0,1]]
transpose = zip(*matrix)
diagonal1 =  []
for n,elem in enumerate(matrix):
    diagonal1.append(elem[n])
diagonal2 = []
for n,elem in enumerate(transpose):
    diagonal2.append(elem[n])
for row in matrix:
    if reduce(lambda x,y: x and y, row):
        print True
        sys.exit()
for row in transpose:
    if reduce(lambda x,y: x and y, row):
        print True
        sys.exit()
if (reduce(lambda x,y: x and y, diagonal1) or reduce(lambda x, y: x and y, diagonal2)):
    print True
    sys.exit()

答案 2 :(得分:0)

根据我对问题的理解,你只需要检查是否有任何行,coloumn或对角线完全由'1'组成。这可以使用Python中的all非常容易地完成,所以我不明白为什么要以递归方式执行此操作。

更明显的解决方案(在我看来)是这样的:

#! /usr/bin/env python
boards=[
        ((0,1,0),(1,0,1),(0,1,0)),
        ((1,1,1),(0,0,0),(0,0,0)),
        ((0,0,0),(1,1,1),(0,0,0)),
        ((0,0,0),(0,0,0),(1,1,1)),
        ((1,0,0),(1,0,0),(1,0,0)),
        ((0,1,0),(0,1,0),(0,1,0)),
        ((0,0,1),(0,0,1),(0,0,1)),
        ((1,0,0),(0,1,0),(0,0,1)),
        ((0,0,1),(0,1,0),(1,0,0)),
        ((0,0,0),(0,0,0),(0,0,0))
]

def check(board):
        for row in board:
                if all(row):
                        return True
        for col in xrange(len(board)):
                vector=[board[row][col] for row in xrange(len(board))]
                if all(vector):
                        return True
        diag1=[board[i][i] for i in xrange(len(board))]
        if all(diag1):
                return True

        diag2=[board[i][i] for i in xrange(len(board)-1,-1,-1)]
        if all(diag2):
                return True

        return False

if __name__=='__main__':
        for board in boards:
                if check(board):
                        print "Yes"
                else:
                        print "No"