簡體   English   中英

返回遞歸 function 與返回存儲遞歸 function 值的變量

[英]Returning recursive function vs. returning variable that stores value of recursive function

這兩個函數返回不同的結果。 他們看起來和我一模一樣。 這里發生了什么?

def DFS(r, c, grid):
   if (r<0 or r>=len(grid) or c<0 or c>=len(grid[0])):
      return False
   if (grid[r][c] == 1):
      return True
      
      grid[r][c]=1
      return DFS(r+1, c, grid) and DFS(r-1, c, grid) and DFS(r, c+1, grid) and DFS(r, c-1, grid)

def DFS(r, c, grid):
   if (r<0 or r>=len(grid) or c<0 or c>=len(grid[0])):
      return False
   if (grid[r][c] == 1):
      return True
   grid[r][c] = 1

   down = DFS(r+1, c, grid)
   up = DFS(r-1, c, grid)
   right = DFS(r, c+1, grid)
   left = DFS(r, c-1, grid)
   return down and up and right and left

例如在這個代碼塊中,

for r in range(len(grid)):
            for c in range(len(grid[0])):
                if (grid[r][c] == 0):
                    #print("searching", r, c)
                    if (DFS(r, c, grid) == True):
                        print([r,c])
                        result+=1
        return result

給定此輸入時,兩個 DFS 函數將返回不同的值:

[[0,0,1,1,0,1,0,0,1,0],[1,1,0,1,1,0,1,1,1,0],[1,0,1,1,1,0,0,1,1,0],[0,1,1,0,0,0,0,1,0,1],[0,0,0,0,0,0,1,1,1,0],[0,1,0,1,0,1,0,1,1,1],[1,0,1,0,1,1,0,0,0,1],[1,1,1,1,1,1,0,0,0,0],[1,1,1,0,0,1,0,1,0,1],[1,1,1,0,1,1,0,1,1,0]]

謝謝您的幫助!

第一個版本使用短路評估來評估對 DFS 的最后 4 個調用:即,如果 return 語句中的第一個 DFS 調用返回一個錯誤值, and運算符甚至不會費心評估接下來的 3 個 DFS 調用。

最后一個版本首先明確評估所有 4 個 DFS 調用,然后才評估 4-way and .

我猜這會對grid[r][c] = 1行的執行頻率和時間產生影響,這可以解釋為什么它們的行為不同。

在另一個答案中有一個聲明:

我猜這會對grid[r][c]=1行的執行頻率和時間產生影響,這可以解釋為什么它們的行為不同。

這個猜測是正確的,下面的代碼證明了第二個 function 等同於第一個。 assert result_1 == result_2沒有引發斷言錯誤表明這兩個函數現在以相同的方式工作:

# These two functions are returning different results. 
# They look identical to me. What is going on here?
def DFS1(r, c, grid):
   if (r<0 or r>=len(grid) or c<0 or c>=len(grid[0])):
      return False
   if (grid[r][c] == 1):
      return True
      
   grid[r][c]=1

   return DFS1(r+1, c, grid) and DFS1(r-1, c, grid) and DFS1(r, c+1, grid) and DFS1(r, c-1, grid)
# The functions in your question were not equivalent. 
# The equivalent function to this above will be: 
def DFS2(r, c, grid):
    if (r<0 or r>=len(grid) or c<0 or c>=len(grid[0])):
       return False
    if (grid[r][c] == 1):
       return True

    grid[r][c] = 1

    if down:= DFS2(r+1, c, grid):
        if up:= DFS2(r-1, c, grid):
            if right:= DFS2(r, c+1, grid):
                if left:= DFS2(r, c-1, grid):
                    return True                    
                      # ^-- as (down and up and right and left) == True
    return False    
    #   ^-- as (down and up and right and left) == False
# For example in this code block,
result_1 = 0
grid = [[0,0,1,1,0,1,0,0,1,0],[1,1,0,1,1,0,1,1,1,0],[1,0,1,1,1,0,0,1,1,0],[0,1,1,0,0,0,0,1,0,1],[0,0,0,0,0,0,1,1,1,0],[0,1,0,1,0,1,0,1,1,1],[1,0,1,0,1,1,0,0,0,1],[1,1,1,1,1,1,0,0,0,0],[1,1,1,0,0,1,0,1,0,1],[1,1,1,0,1,1,0,1,1,0]]
for r in range(len(grid)):
    for c in range(len(grid[0])):
        if (grid[r][c] == 0):
            #print("searching", r, c)
            if (DFS1(r, c, grid) == True):
                print([r,c])
                result_1+=1

result_2 = 0
print(' --- ' )
grid = [[0,0,1,1,0,1,0,0,1,0],[1,1,0,1,1,0,1,1,1,0],[1,0,1,1,1,0,0,1,1,0],[0,1,1,0,0,0,0,1,0,1],[0,0,0,0,0,0,1,1,1,0],[0,1,0,1,0,1,0,1,1,1],[1,0,1,0,1,1,0,0,0,1],[1,1,1,1,1,1,0,0,0,0],[1,1,1,0,0,1,0,1,0,1],[1,1,1,0,1,1,0,1,1,0]]
for r in range(len(grid)):
    for c in range(len(grid[0])):
        if (grid[r][c] == 0):
            #print("searching", r, c)
            if (DFS2(r, c, grid) == True):
                print([r,c])
                result_2+=1

# These two DFS functions above will return the same values. 
assert result_1 == result_2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM