家庭作业中的递归错误。寻求建议

时间:2014-04-16 19:51:19

标签: python recursion

我参加了一个介绍comp sci课程,目前的项目是递归的。该程序读取的文本文件包含n行和-I的n列。该程序创建一个2D列表 这是用于该程序的网格。然后提示用户在网格上的一个点(行,列),如果用户的点是-,则该点被更改为@,然后我必须递归填充在@的第一个可用空间中,检查上方,左侧,右侧,下方的空间并填充第一个可用空间。我的递归函数是:

def fillWithAt(grid, the_row, the_col):

    if grid[the_row][the_col] == '-':
        grid[the_row][the_col] = '@'
        printFile(grid)

        if the_row != 0:
            if grid[the_row - 1][the_col] == '-':
                fillWithAt(grid, the_row - 1, the_col)

        if the_col != 0:
            if grid[the_row][the_col - 1] == '-':
                fillWithAt(grid, the_row, the_col - 1)

        if the_col != (len(grid[the_row]) - 1):
            if grid[the_row][the_col + 1] == '-':
                fillWithAt(grid, the_row, the_col + 1)

        if the_row != (len(grid) - 1):
            if grid[the_row + 1][the_col] == '-':
                fillWithAt(grid, the_row + 1, the_col)

    else:
        printFile(grid)

grid是2D列表,the_row是用户的行,the_col是用户的列。 该程序几乎完美地工作,但它到达最后两列时会崩溃。 我无法弄清楚如何将输出复制到此中,因为每次尝试都会删除空白并且没有任何意义,所以我会尝试解释。

该程序正常工作,直到我击中最后两行。程序在右边找到一个空的空间,由于某种原因占据了右边的下两个空格而不是一个空格。之后程序错误地读取当前点周围的空格。在一天结束时,程序仍然完成任务,但我很好奇为什么会发生错误。

我不是在寻找任何答案,而是建议。如果有人能够看到任何可能发生这种情况的原因,我会感激任何信息。我也喜欢反馈/建设性的批评。

编辑:以下是递归过程的几个步骤。当前空间首先在邻居上方查看' - '。如果找到破折号,那么该空间被占用,如果没有,则检查左邻居,然后是右边,最后是下面。

- - - - - I I - - - - - - - -
- - - - I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ - - - - I I - - - - - - - -
- - - - I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ - - - I I - - - - - - - -
- - - - I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ - - I I - - - - - - - -
- - - - I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ - I I - - - - - - - -
- - - - I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ @ I I - - - - - - - -
- - - - I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ @ I I - - - - - - - -
- - - @ I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ @ I I - - - - - - - -
- - @ @ I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ @ I I - - - - - - - -
- @ @ @ I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ @ I I - - - - - - - -
@ @ @ @ I - - I I - - - - - -
- - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

@ @ @ @ @ I I - - - - - - - -
@ @ @ @ I - - I I - - - - - -
@ - - - I - - - - I I I I - -
- - - I - - - - - - - - I I I
- - I - - - - - - - - - - - -
- - - I - - - - - - - - I I I
- - - I - - I I I - - - I - -
- - - I - - I - - I - I - - -
- - - I I I I - - - I - - - -
- - - - - - - - - - - - - - -

该程序按预期工作至此为止:

@ @ @ @ @ I I - - - - - - - -
@ @ @ @ I - - I I - - - - - -
@ @ @ @ I - - - - I I I I - -
@ @ @ I - - - - - - - - I I I
@ @ I - - - - - - - - - - - -
@ @ @ I - - - - - - - - I I I
@ @ @ I - - I I I - - - I - -
@ @ @ I - - I @ @ I - I @ - -
@ @ @ I I I I @ @ @ I @ @ - -
@ @ @ @ @ @ @ @ @ @ @ @ - - -

@ @ @ @ @ I I - - - - - - - -
@ @ @ @ I - - I I - - - - - -
@ @ @ @ I - - - - I I I I - -
@ @ @ I - - - - - - - - I I I
@ @ I - - - - - - - - - - - -
@ @ @ I - - - - - - - - I I I
@ @ @ I - - I I I - - - I - -
@ @ @ I - - I @ @ I - I @ @ @
@ @ @ I I I I @ @ @ I @ @ - -
@ @ @ @ @ @ @ @ @ @ @ @ - - -

@ @ @ @ @ I I - - - - - - - -
@ @ @ @ I - - I I - - - - - -
@ @ @ @ I - - - - I I I I - -
@ @ @ I - - - - - - - - I I I
@ @ I - - - - - - - - - - - -
@ @ @ I - - - - - - - - I I I
@ @ @ I - - I I I - - - I @ @
@ @ @ I - - I @ @ I - I @ @ @
@ @ @ I I I I @ @ @ I @ @ - -
@ @ @ @ @ @ @ @ @ @ @ @ - - -

由于某种原因,它占据了右边的两个空格而不是一个,然后在下一个移动中它占据了两个先前占用的空间之上的两个空间。

生成网格的代码是:

def get2DList(fo):
    full_list = []

    for line in fo:
        full_list.append(list(line.strip()))

    fo.close()
    return full_list

fo是一个文件

编辑:我已经解决了我的问题,感谢@Blckknght让我知道我的printFile()函数是原因。它现在工作得很好。感谢所有帮助过的人!

2 个答案:

答案 0 :(得分:2)

我试图找出问题并重新编写了你的​​程序。然后我注意到你解决了你的问题,但它并不明显,因为你没有接受答案。我建议@Blckknght应发表他的评论"我想知道是否有输出错误"作为答案你应该接受它。然后人们就会确定这个问题已经解决了。

你可以查看我的版本,看看你对它的看法。

我可能在Python中使用了一些你尚未学到的东西。如果是这样,我现在就忽略它。

的变化:

  • 我添加了一个字符串来初始化网格,以及一个从字符串中生成网格的函数

  • 我将the_row更改为row,同样更改为the_col。前缀the_只会增加视觉噪音。

  • 我做了一个外部函数,有一次,对输入网格进行完整性检查,然后是一个只进行递归填充的内部函数。

  • 我刚刚重新编写print_grid()以使用直接在网格上循环的for循环,而不是使用range()。这个代码更干净,运行速度更快。

  • 我使用''.join(row)打印出网格,它不会将网格字符与空格分开。这与你的做法不同。要获取空格,只需执行以下操作:' '.join(row)换句话说,使用空格而不是空字符串连接行。

  • 我写这篇文章是为了在Python 2.x或Python 3.x上运行unchnaged。唯一棘手的问题是我必须调用'print('')而不是print(),因为在Python 2.x中print()实际上会打印()而不是什么。 (这是因为在Python 2.x中,print是一个语句而不是一个函数,它将()计算为空元组,并将空元组打印为()!)

  • 我更改了所有名称以符合PEP8标准。 (但如果你上课,老师要你使用camelCase名字,那就按照老师的说法做。)

http://legacy.python.org/dev/peps/pep-0008/

# grid flood fill program
# http://en.wikipedia.org/wiki/Flood_fill

s_grid = """\
-----II--------
----I--II------
----I----IIII--
---I--------III
--I------------
---I--------III
---I--III---I--
---I--I--I-I---
---IIII---I----
---------------
"""

def grid_from_str(s):
    s = s.strip()
    rows = s.split('\n')
    return [list(row) for row in rows]

def print_grid(grid):
    for row in grid:
        print(''.join(row))
    print('')


def flood_fill(grid, row, col, blank='-', fill='@'):
    row_max = len(grid)
    col_max = len(grid[row])

    if grid[row][col] != blank:
        print("skipping: row {}, col {}".format(row, col))
        return

    grid[row][col] = fill
    print_grid(grid)

    if row > 0:
        if grid[row - 1][col] == blank:
            flood_fill(grid, row - 1, col)

    if col > 0:
        if grid[row][col - 1] == blank:
            flood_fill(grid, row, col - 1)

    if col < (len(grid[row]) - 1):
        if grid[row][col + 1] == blank:
            flood_fill(grid, row, col + 1)

    if row < (len(grid) - 1):
        if grid[row + 1][col] == blank:
            flood_fill(grid, row + 1, col)


def fill_grid_with_at(grid, row, col):
    row_max = len(grid)
    col_max = len(grid[0])

    assert row_max > 0 and col_max > 0

    # make sure grid is regular
    assert all(col_max == len(row) for row in grid)

    # make sure grid only contains legal stuff
    assert all(ch in ('-', 'I', '@') for row in grid for ch in row)

    flood_fill(grid, row, col)


grid = grid_from_str(s_grid)
fill_grid_with_at(grid, 0, 0)

答案 1 :(得分:0)

在第一次提出这些功能时,我犯了一个粗心的错误。因此我的printFile()就是

def printFile(current_list):
    for i in current_list:
        for j in i[:-1]:
            print(j, end = ' ')
        print(j)
    print()

我的理由是,当我第一次尝试时,我只使用for j in i: print(j, end = ' ')问题是它会在每一个新行前面打印出不需要的空间,这是我想到的第一件事。

我现在看到在最后一列for循环之外打印j是一个错误,因为j仍然等于for循环的前一次迭代,导致最后两列行为同样的(我是新手所以请不要嘲笑我)。我的新功能是:

def printFile(current_list):
    for i in current_list:
        print(' '.join(i))
    print()

现在一切正常。再次感谢所有帮助过的人。