递归函数中的计数器



我对python和编程都是新手。我写了一个函数,它将在数组中搜索相邻的元素,并寻找彼此的值在0.05以内的元素,就像洪水填充算法一样。唯一的区别是,在计算函数运行多少时间时,我做了一些愚蠢的事情(我认为这也会告诉我找到了多少个元素),所以我的计数器值是错误的。当涉及到查找相邻元素在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 1count1 2count1 3count1 4count1 5是从5是从4是从3count1 3是从3是从2是从1

你可以看到有些东西很可疑:p谁能指出我做错了什么吗?

所以floodcount()返回新的count值。但是你从不存储/使用它:)

替换为:

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

:

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

除了已经解决的计数问题:

你可以减少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

您获得的结果是预期的

UPDATE:我的解释(下面)不完全正确。(感谢Ben的启蒙)。(然而,我的解决方案建议是正确的)

count实参通过value传递给递归调用and不是通过引用。这意味着在子调用中进行的增量对当前函数中的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)

您递归地调用floodcount,为其提供当前的count以开始,并且它在完成时忠实地返回它所拥有的count。然后忽略它,并使用传递给第一次递归调用的相同count继续进行下一个递归调用。尝试更改所有对count = floodcount(...)的递归调用。

如果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

最新更新