递归函数中的计数器

时间:2011-12-14 07:06:36

标签: python recursion

我是python和编程的新手。我编写了一个函数,它将搜索数组中的相邻元素,并寻找值相互之间0.05的值,就像泛光填充算法一样。唯一的区别是我在计算函数运行的时间时做了一些愚蠢的事情(我想这也会告诉我我发现了多少元素),所以我的计数器值是错误的。该代码适用于在相互之间找到相邻元素,只是计数很有趣。

def floodcount (x,y,array,value,count=0):     #akin to a bucket fill in paint, finds the area instead

    nrows = len(array)-1          #rows of the image
    ncols = len(array[0])-1       #columns of the image
    diff = array[x][y] - value
    if (diff < 0.00) or (diff > 0.05): # the base case, finding a diff more than 0.05 or less than 0 is like finding a boundary
        return 0

    count = count +1
    print 'count1 ',count

    array[x][y] = -5 # so we do no calculate this pixel again
    #print "[",x,",",y,"]"
    if x > 0:
        #print '1'# if not the first elemnet then can go back, this makes sure that x is within the array all the time
        floodcount (x-1,y,array,value,count)
    if y > 0:
        #print '2'
        floodcount (x,y-1,array,value,count) 
    if x < nrows:
        #print '3'
        floodcount (x+1,y,array,value,count)
    if y < ncols:
        #print '4'
        floodcount (x,y+1,array,value,count)
    if x > 0 and y > 0:
        #print '5'
        floodcount (x-1,y-1,array,value,count)
    if x < nrows and y < ncols:
        #print '6'
        floodcount (x+1,y+1,array,value,count)
    if x <nrows and y > 0:
        #print '7'
        floodcount (x+1,y-1,array,value,count)
    if x > 0 and y < ncols:
        #print '8'
        floodcount (x-1,y+1,array,value,count)

    print 'count2 ',count    
    return count

因此对于测试用例

array = [[5,1,1,3,4],[4,5,6,2,5],[5,8,5,5,9]] x = 0且y = 0

输出

count1 1 count1 2 count1 3 count1 4 count1 5 count2 5 count2 4 count2 3 count1 3 count2 3 count2 2 count2 1

你可以看到有些东西是可疑的:P 谁能指出我做错了什么?任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:3)

因此floodcount()返回新的count值。但你永远不会存储/使用它:)

替换以下行:

floodcount(x+1, y-1, array, value, count)

使用:

count = floodcount(x+1, y-1, array, value, count)

答案 1 :(得分:2)

您获得的结果是预期的

更新:我的解释(此处)不完全正确。 (感谢Ben的启示)。 (尽管如此,我的解决方案提案是正确的)

  

count参数通过按值传递给递归调用和   不是参考。这意味着您在子查询中进行的递增对当前函数中的count变量没有影响   (=本地函数变量)。

您可以使用全局变量来实现想要的结果:

count = 0
def floodcount (x,y,array,value):
    global count
    ...

或者通过在包装类中使用计数器(通过引用传递对象):

class CounterClass:
    cnt = 0

def floodcount (x,y,array,value, counter):
    ...
    counter.cnt += 1
    ...

否则:返回您的函数生成的计数器:

count = floodcount(x+1, y-1, array, value, count)

答案 2 :(得分:2)

除了现在解决的计数问题:

您可以通过每次执行所有递归调用来减少if语句的数量,只需使用if x < 0 or y < 0 or x > nrows or y > ncols检查函数开头的数组边框。

#akin to a bucket fill in paint, finds the area instead
def floodcount (x,y,array,value,count=0): 
    nrows = len(array)-1          #rows of the image
    ncols = len(array[0])-1       #columns of the image
    if x < 0 or y < 0 or x > nrows or y > ncols:
        return count

    diff = array[x][y] - value
    # the base case, finding a diff more than 0.05 or less than 0 is like finding a boundary
    if (diff < 0.00) or (diff > 0.05): 
        return count

    count = count +1
    print 'count1 ',count

    array[x][y] = -5 # so we do no calculate this pixel again
    #print "[",x,",",y,"]"

    count = floodcount (x-1,y,array,value,count)
    count = floodcount (x,y+1,array,value,count)
    count = floodcount (x+1,y,array,value,count)
    count = floodcount (x,y-1,array,value,count)

    count = floodcount (x-1,y-1,array,value,count)
    count = floodcount (x+1,y+1,array,value,count)
    count = floodcount (x+1,y-1,array,value,count)
    count = floodcount (x-1,y+1,array,value,count)

    print 'count2 ',count    
    return count

答案 3 :(得分:1)

您以递归方式调用floodcount,将当前count提供给它开始,并尽职尽责地返回它完成时的count。然后你忽略它,并继续使用你传递给第一个递归调用的相同count的下一个递归调用。尝试将所有递归调用更改为count = floodcount(...)

答案 4 :(得分:0)

如果xy都大于0,您将运行floodcount()两次。那是你要的吗?看起来你只想在数组中每个元素运行一次floodcount。如果是这种情况,请修改您的代码以使用if/elif而不仅仅是if

if x > 0:
    floodcount (x-1,y,array,value,count)
elif y > 0:
    floodcount (x,y-1,array,value,count) 

#elif all the rest