在矩阵a中找到最长的字符串,递归地 - Python

时间:2015-03-24 10:25:17

标签: python algorithm recursion matrix vector

我想使用递归找到给定矩阵中最长的字符串(最重复的char)。用户给出的输入是矩阵,以及递归的起始位置。另一件事是矩阵的每个元素都可以被检查"通过递归函数只有一次。

所以这是一个例子:

如果我的矩阵看起来像这样:

abcdeaab
adfdgagh
madafaff
abaacafr

结果应为start=(5,0), stop=(5,4), c='a'。结果就是这样,因为char' a'是矩阵中最长的字符串,它从位置(5,0)开始,到(5,4)结束。如您所见,矩阵必须水平和垂直检查。

我过去并没有真正使用太多的递归,这就是我被困在这里的原因。

我在这里阅读了这篇文章:http://interactivepython.org/courselib/static/pythonds/Recursion/recursionsimple.html。我明白为了实现我想要实现的目标,我的程序必须遵守递归的三个定律:

  • 递归算法必须具有基本情况。
  • 递归算法必须改变其状态并向基本情况移动。
  • 递归算法必须递归调用自身。

我开始编写代码,然后到了这里:

#!/bin/python2.7

#Longest string in matrix

#Given a matrix filled with letters. Find the longest string, containing only the same letter, which can be obtained by starting
#with any position and then moving horizontally and vertically (each cell can be visited no more than 1 time).


# Settings here
# -------------
string_matrix = """
abcdeaab
adfdgagh
madafaff
abaacafr
"""
pos = (0,0)
# -------------

rows = 0
columns = 0
matrix = []
matrix2 = []


def stop():
    for l in matrix2:
        for c in l:
            if c == '1':
                return True
    return False

def search(pos):
    # my base case
    if stop():
        return

    global matrix2
    # matrix2 keeps track of the visited elements of matrix
    matrix2[pos[0]][pos[1]] = 1



def main():
    # create the matrix from string
    string_matrix_l = string_matrix.strip()
    splited = string_matrix_l.split('\n')

    global rows
    global columns
    global matrix
    global matrix2

    rows = len(splited)
    columns = len(splited[1])

    # initialize matrix with 0
    matrix = [[0 for x in range(columns)] for x in range(rows)]
    matrix2 = [[0 for x in range(columns)] for x in range(rows)]

    # print some info
    print 'Given matrix: ' + str(matrix) + '\n'
    print 'Start position: ' + str(pos)

    # set matrix from string
    i = 0
    for s in splited:
        s = s.strip()
        if s == '':
            continue

        j = 0

        for c in s:
            try:
                matrix[i][j] = c
                #print 'ok: ' + str(i) + ' ' + str(j) + ' ' +  c
            except:
                print 'fail: index out of range matrix[' + str(i) + '][' + str(j)+'] ' + c
            j = j + 1

        i = i + 1

        #print s
        #print matrix


    # get the result
    search(pos)

if __name__ == "__main__":
    main()

我的程序(目前)正在将字符串转换为矩阵,并创建另一个矩阵,称为matrix2,它将跟踪搜索(递归)函数从矩阵访问的元素。

任何建议都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

首先,这个问题很难解决,并且没有已知的有效解决方案,它被称为Longest Path Problem

要从一个单元格中找到最长路径,可以使用DFS来解决它,这本质上是递归算法。

Python就像伪代码一样:

DFS((x,y),visited):
   maxPathLength = -1
   for each neighbor (x1,y1) of (x,y):
        #skip visited nodes, or nodes that are not the same character:
        if (x1,y1) in visited of arr[x][y] != arr[x1][y1]:
           continue
        #node is not visited and same character.
        #mark it as visited:
        visited.add((x1,y1))
        #recurse and store what the longest path found by recursion:
        currLength = DFS((x1,y1),visited)
        #set the max out of all paths:
        maxPathLength = max(maxPathLength, currLength)
   #clean up
   visited.remove((x,y))
   #return an answer:
   return maxPathLength  + 1

它遵循你的3点递归算法,因为:

  • 代码中的stop子句:如果没有“未访问”的节点,则 算法将返回0而不调用递归调用。
  • 算法改变被访问节点的状态,然后移动到下一个邻居,直到没有可能的路径,这将是stop子句。
  • 该算法以递归方式为当前单元格的每个可能“邻居”调用自身。

此算法将为您提供来自某个源单元的最长路径。您可以为所有单元格重复它以找到“全局”最长路径。

此算法仅提供最长路径的长度,但通过返回元组(length,list)来修改它以记住路径本身非常容易 - 其中list是在这条路上访问过的小区。