簡體   English   中英

查找列表中僅相差一個字母的所有單詞

[英]Find all the words in the list that differ by a single letter

對於列表words中的任何給定單詞w ,我想通過更改其中的單個字母來找到列表中可以變成w的所有其他單詞。 所有的詞都是等長的,只允許替換。 稱此為 function parent(w)

例如,給定words = ["hot","dot","dog","lot","log","cog"]parent("cog")將是["dog", "log"] parent("lot")將是["dot", "hot", "log"]等。

為此,我首先構建一個反向索引,其中鍵(str, int) map 指向在索引int處具有字符str的單詞。 然后,找到一個單詞的雙親就變成了將所有與該單詞在相同位置具有相同字母的單詞相交的任務,除了一個。

代碼如下,產生一個空集。 為什么它不起作用?

from typing import Iterator, Dict, Tuple, Set
import itertools

graph: Dict[Tuple[str, int], Set[int]] = dict()

for i, word in enumerate(words):
    for j, ch in enumerate(word):
        if (ch, j) not in graph:
            graph[(ch, j)] = set()

        graph[(ch, j)].add(i)

def parents(word: str) -> Iterator[int]:
    n: int = len(word)
    s: Set[int] = set()
    for part in itertools.combinations(range(n), n - 1):
        keys = map(lambda x: (word[x], x), part)
        existing_keys = filter(lambda k: k in graph, keys)
        for y in itertools.chain(map(lambda k: graph[k], existing_keys)):
            s = s.intersection(set(y)) if s else set(y)

    return filter(lambda i: words[i] != word, s)

print(list(parents("cog"))) # empty!!!

您的解決方案幾乎就緒。 問題是您正在與找到的所有內容相交。 但是你應該 append 每個組合的結果。 在第一個 for 循環內移動s: Set[int] = set() ,在第二個 for 循環后移動 append 結果,它會起作用。 像這樣:

def parents(word: str) -> Set[int]:
    ret: Set[int] = set()
    for part in itertools.combinations(range(n), n - 1):
        keys = map(lambda x: (word[x], x), part)
        existing_keys = filter(lambda k: k in graph, keys)
        s: Set[int] = set()
        for y in map(lambda k: graph[k], existing_keys):
            s = s.intersection(set(y)) if s else set(y)

        ret.update(filter(lambda i: words[i] != word, s))

    return ret

Levenshtein 距離算法將實現您正在尋找的內容。

from Levenshtein import distance  # pip install python-Levenshtein

words = ["hot", "dot", "dog", "lot", "log", "cog"]
parent = 'cog'
# find all words matching with one substitution
edits = [w for w in words if distance(parent, w) == 1]
print(edits)

Output:

['dog', 'log']

如果您不想安裝任何庫,可以使用具有 Python 算法實現的良好在線資源

一個非常簡單的解決方案。 一種不同的方法。

復雜度: O(N * 26) => O(N) - 其中 N 是每個單詞中的字符數。

def main(words, word):
    words = set(words)
    res = []
    for i, _ in enumerate(word):
        for c in 'abcdefghijklmnopqrstuvwxyz':
            w = word[:i] + c + word[i+1:]
            if w != word and w in words:
                res.append(w)
    return res


print(main(["hot","dot","dog","lot","log","cog"], "cog"))
# ['dog', 'log']

除了迭代所有字母表,您還可以選擇僅迭代列表中出現的字母表,使用:

{letter for w in words for letter in w}

我會使用 function 中的 Python 對照列表中的每個單詞檢查父單詞 w 的每個字母。

例如,針對單詞列表的parent("cog")

["hot","dot","dog","lot","log","cog"]

產量:

[1, 1, 2, 1, 2, 3]

數字 2 顯示正確的單詞:dog 和 log。

暫無
暫無

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

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