我对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(...)
的递归调用。
如果x
和y
都大于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