簡體   English   中英

修改遞歸 function 中的集合?

[英]Modifying a set within a recursive function?

我正在嘗試編寫一個程序來檢查是否可以使用給定的“boggle board”來制作特定的單詞。 挑戰的完整細節在這里: Boggle Word Checker

基本上,該程序應該在板上找到單詞的第一個字母,然后檢查板上的任何相鄰字母是否與該單詞的下一個字母匹配。

這是我到目前為止所得到的(我不太清楚):

def pos(board, x, y):
    # function to get value from a grid, but return None if not on grid,to
    # prevent wraparound
    if x >= 0 and y >= 0 and x < len(board[0]) and y < len(board):
        return board[y][x]
    else:
        return None

def surrounds(board, x, y):
    # make a dictionary which to store the positions and values of adjacent
    # letters on board, given a single postision as input
    return {
        (x-1,y-1) : pos(board,x-1,y-1), #aboveLeft
        (x,y-1) : pos(board,x,y-1),     #aboveMiddle etc...
        (x+1,y-1) : pos(board,x+1,y-1),
        (x-1,y) : pos(board,x-1,y),
        (x+1,y) : pos(board,x+1,y),
        (x-1,y+1) : pos(board,x-1,y+1),
        (x,y+1) : pos(board,x,y+1),
        (x+1,y+1) : pos(board,x+1,y+1)
    }

def find_word(board, word):
    # initialise
    listOfCoords = []

    # find all occurrences of the first letter, and store their board
    # position in a list
    for i in range(len(board)):
        for j in range(len(board[0])):
            if board[i][j] == word[0]:
                listOfCoords.append([j,i])

    print('list of ' + word[0] + 's on board:')
    print(listOfCoords)
    print()

    # if word is only 1 letter long then we can return True at this point
    if listOfCoords and len(word) == 1:
        return True

    # otherwise we move on to look for the second letter
    return findnext(board,word,listOfCoords)

def findnext(board, word, mylist):
    for x, y in mylist:
        print("Current coords: {},{}\n".format(x,y))
        surroundings = surrounds(board,x,y)

        listFounds = []

        for k, v in surroundings.items():

            if v == word[1]:
                print("{} found at {}".format(v,k))
                print()

                if len(word) == 2:
                    print()
                    return True

                listFounds.append(k)

                if findnext(board, word[1:], listFounds) == True:
                    return True
    return False

testBoard = [
      ["E","A","R","A"],
      ["N","L","E","C"],
      ["I","A","I","S"],
      ["B","Y","O","R"]
    ]

print(find_word(testBoard, "CEREAL"))

但是,我遇到了一個問題,因為挑戰指定板上沒有 position 可以多次使用。 因此,在上面的示例中,程序應該為“CEREAL”返回 False,但我的返回 True。

我在想解決這個問題的方法是使用一個集合,一旦找到下一個字母,它就會將坐標添加到集合中。 但是,對於需要在哪里創建空集,以及它將如何與所有循環和遞歸一起工作,我有點迷茫......

例如,假設我們在另一塊板上尋找“CEREAL”,它有 2 個 E 與 C 相鄰。 假設第一條路徑只通向 CER,另一條通向 CEREAL。 如果我們首先沿着 CER 路徑 go,它的位置將被添加到集合中,並且我需要在它沿着 CEREAL 路徑之前再次刪除它們。

我正在努力思考如何在我的程序中實現這一點。

您需要將一個布爾值數組設置為棋盤大小,全部設置為 False。 當您使用字母並遞歸調用 function 時,請將所用字母的單元格設置為 True。 從遞歸調用返回時,將單元格值設置回 False。 您應該只使用帶有 False 值的字母,表明它們以前沒有被使用過。

或者,您可以在將字母保存在臨時變量中之后用 None 替換使用的字母,然后進行遞歸調用。 從遞歸調用返回后,從 temp 變量中放回單元格的值。

腳步:

  1. 找到與棋盤的第一個字符匹配
  2. 找到匹配項后,使用回溯執行DFS ,直到您完全匹配該單詞或由於不匹配而耗盡搜索。
  3. 如果在上述步驟中沒有找到完全匹配,則繼續掃描板。 (即 go 到第 1 步)用於匹配板上的下一個字符。
  4. 如果在步驟 3 中找到匹配項,則報告成功。

該解決方案也適用於NxM板。

def is_within_bounds(row, col, row_dim, col_dim):
    return row >= 0 and row < row_dim and col >= 0 and col < col_dim


def get_neighbors(row, col, row_dim, col_dim):
    for r_offset in (-1, 0, 1):
        for c_offset in (-1, 0, 1):
            if r_offset == 0 and c_offset == 0:
                continue
            r_new = row + r_offset
            c_new = col + c_offset
            if is_within_bounds(r_new, c_new, row_dim, col_dim):
                yield (r_new, c_new)


def is_word_found(board, word, row, col, visited):
    if word[0] != board[row][col]:
        return False
    if len(word) == 1:
        return True
    for neighbor in get_neighbors(row, col, len(board), len(board[0])):
        if neighbor not in visited:
            visited.add(neighbor)
            if is_word_found(board, word[1:], neighbor[0], neighbor[1], visited):
                return True
            visited.remove(neighbor)
    return False


def find_word(board, word):
    for row in range(len(board)):
        for col in range(len(board[0])):
            if word[0] != board[row][col]:
                continue
            if is_word_found(board, word, row, col, set()):
                return True
    return False

暫無
暫無

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

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