找到符合给定单词的列表中单词的所有排列。

huangapple go评论69阅读模式
英文:

Find all permutations of words from list that fits in given word

问题

def letterCombinations(word, valid_words):
    result = []
    
    def dfs(string_path, valid_word_set, curr_combination):
        if not string_path:
            result.append(curr_combination.copy())
            return

        for i in range(1, len(string_path) + 1):
            if string_path[:i] in valid_word_set:
                curr_combination.append(string_path[:i])
                dfs(string_path[i:], valid_word_set, curr_combination)
                curr_combination.pop()

    valid_word_set = set(valid_words)
    dfs(word, valid_word_set, [])
    
    return result

This modified code should produce the desired result. It uses depth-first search (DFS) to generate combinations of valid words from the input word, considering valid words in the valid_words list. The result is stored in the result list as a list of lists, where each inner list represents a valid combination of words.

英文:

If I had the word "sometime" and I have the list of words

valid_words: ["some","time","rome","sometime","so","me"]

I want to output the result

result = [["so","me","time"],["some","time"],["sometime"]]

I know I should be using DFS, but I have no idea how to code it. I struggle with permutations. Can somebody help me?

This is what I have so far

def letterCombinations(word, valid_words):
    result = []
    def dfs(string_path, i, valid_word_set, curr_string):
      if i == len(word):
        return

      if string_path[:i] in valid_word_set:
        curr_string.append(string_path[:i])
        dfs(string_path[i:], i+1, valid_word_set, curr_string)
      else:
        dfs(string_path, i+1, valid_word_set, curr_string)
        
    for i in range(0, len(word)):
        if word[:i] in valid_words:
          curr_string = [word[:i]]
          dfs(word[i:], i, valid_words, curr_string)
          result.append(curr_string)
    
    return result

答案1

得分: 2

这应该适合你的需求。
它使用递归来遍历所有的组合,并将找到的单词存储在集合中,因此实际上进行了缓存。

def letter_combos(word: str, word_dict: list[str]) -> list[list[str]]:
    def dfs(word: str, valid_word_set: set[str], start: int, memo: dict[int, list[list[str]]]) -> list[list[str]]:
        if start in memo:
            return memo[start]
        res: list[list[str]] = []
        if start == len(word):
            res.append([])
        for end in range(start + 1, len(word) + 1):
            if word[start:end] in word_dict:
                list_of_words = dfs(word, valid_word_set, end, memo)
                for lst in list_of_words:
                    res.append([word[start:end]] + lst)
        memo[start] = res
        return res
    return dfs(word, set(word_dict), 0, {})

word = "sometime"
valid_words = ["some", "time", "rome", "sometime", "so", "me"]

print(letter_combos(word, valid_words))

# 输出:
# [['so', 'me', 'time'], ['some', 'time'], ['sometime']]

你也可以使用functoolslru_cache来优化这个函数:

from functools import lru_cache

def letter_combos(word: str, valid_words: list[str]) -> list[list[str]]:
    @lru_cache(maxsize=None) 
    def dfs(start: int) -> list[list[str]]:
        if start == len(word):  
            return [[]]
        result: list[list[str]] = []
        for end in range(start + 1, len(word) + 1):
            if word[start:end] in valid_word_set:
                for lst in dfs(end):
                    result.append([word[start:end]] + lst)
        return result

    valid_word_set = set(valid_words)
    return dfs(0)

word = "sometime"
valid_words = ["some", "time", "rome", "sometime", "so", "me"]
print(letter_combos(word, valid_words))

# 输出:
# [['so', 'me', 'time'], ['some', 'time'], ['sometime']]
英文:

This should do the trick for you.
It uses recursion to loop through all the combinations and stores found words in set, so you are essentially caching

def letter_combos(word: str, word_dict: list[str]) -> list[list[str]]:
    def dfs(word: str, valid_word_set: set[str], start: int, memo: dict[int, list[list[str]]]) -> list[list[str]]:
        if start in memo:
            return memo[start]
        res: list[list[str]] = []
        if start == len(word):
            res.append([])
        for end in range(start + 1, len(word) + 1):
            if word[start:end] in word_dict:
                list_of_words = dfs(word, valid_word_set, end, memo)
                for lst in list_of_words:
                    res.append([word[start:end]] + lst)
        memo[start] = res
        return res
    return dfs(word, set(word_dict), 0, {})

word = "sometime"
valid_words = ["some", "time", "rome", "sometime", "so", "me"]

print(letter_combos(word, valid_words))

>>> [['so', 'me', 'time'], ['some', 'time'], ['sometime']]

You can also use functools lru_cache for this which tidies it up a bit

from functools import lru_cache

def letter_combos(word: str, valid_words: list[str]) -> list[list[str]]:
    @lru_cache(maxsize=None) 
    def dfs(start: int) -> list[list[str]]:
        if start == len(word):  
            return [[]]
        result: list[list[str]] = []
        for end in range(start + 1, len(word) + 1):
            if word[start:end] in valid_word_set:
                for lst in dfs(end):
                    result.append([word[start:end]] + lst)
        return result

    valid_word_set = set(valid_words)
    return dfs(0)

word = "sometime"
valid_words = ["some", "time", "rome", "sometime", "so", "me"]
print(letter_combos(word, valid_words))

答案2

得分: 1

基于 itertools.permutations 和生成器函数的替代解决方案:

from itertools import permutations

def match_perms(word, valid_words):
    words = valid_words[:]
    if word in words:   # 如果整个单词在单词列表中找到
        yield (word,)
        words.remove(word)  # 从排列中排除它
    
    for i in range(2, len(words)):
        for p in permutations(words, i):
            if ''.join(p) == word:
                yield p

print(list(match_perms(word, valid_words)))

[('sometime',), ('some', 'time'), ('so', 'me', 'time')]

英文:

Alternative solution basing on itertools.permutations and generator function:

from itertools import permutations

def match_perms(word, valid_words):
    words = valid_words[:]
    if word in words:   # if the whole word is found in words list
        yield (word,)
        words.remove(word)  # excude it from permutations

    for i in range(2, len(words)):
        for p in permutations(words, i):
            if ''.join(p) == word:
                yield p

print(list(match_perms(word, valid_words)))

[('sometime',), ('some', 'time'), ('so', 'me', 'time')]

答案3

得分: 1

递归方法,还考虑了使用 Counter 来检测潜在重复单词的情况:

from collections import Counter

word = 'sometime'
valid_words = ['some', 'time', 'rome', 'sometime', 'so', 'me']

def find_comb(word, valid_words, stem=None):
    if stem is None:
        stem = []
    if not isinstance(valid_words, Counter):
        valid_words = Counter(valid_words)
    if word in valid_words:
        yield stem + [word]
    for w in valid_words:
        if word.startswith(w):
            yield from find_comb(word[len(w):],
                                 valid_words-Counter({w: 1}),
                                 stem=stem+[w])  
out = list(find_comb(word, valid_words))

输出结果: [['sometime'], ['some', 'time'], ['so', 'me', 'time']]

其他示例:

list(find_comb('banana', ['banana', 'ba', 'na', 'na', 'nana']))
# [['banana'], ['ba', 'nana'], ['ba', 'na', 'na']]

list(find_comb('banana', ['banana', 'ba', 'na', 'nana']))
# [['banana'], ['ba', 'nana']]

请注意,我只提供了代码的翻译部分,没有包含额外的内容。

英文:

A recursive approach, which also takes into account potential duplicated words using Counter:

from collections import Counter

word = 'sometime'
valid_words = ['some', 'time', 'rome', 'sometime', 'so', 'me']

def find_comb(word, valid_words, stem=None):
    if stem is None:
        stem = []
    if not isinstance(valid_words, Counter):
        valid_words = Counter(valid_words)
    if word in valid_words:
        yield stem + [word]
    for w in valid_words:
        if word.startswith(w):
            yield from find_comb(word[len(w):],
                                 valid_words-Counter({w: 1}),
                                 stem=stem+[w])  
    
out = list(find_comb(word, valid_words))

Output: [['sometime'], ['some', 'time'], ['so', 'me', 'time']]

Other examples:

list(find_comb('banana', ['banana', 'ba', 'na', 'na', 'nana']))
# [['banana'], ['ba', 'nana'], ['ba', 'na', 'na']]

list(find_comb('banana', ['banana', 'ba', 'na', 'nana']))
# [['banana'], ['ba', 'nana']]

答案4

得分: 0

def letterCombinations(word, valid_words):
    result = []

    def dfs(string_path, valid_word_set, curr_string):
        if not string_path:
            result.append(curr_string[:])  # 将当前字符串的副本添加到结果列表中
            return

        for i in range(1, len(string_path) + 1):
            if string_path[:i] in valid_word_set:
                curr_string.append(string_path[:i])
                dfs(string_path[i:], valid_word_set, curr_string)
                curr_string.pop()  # 通过从当前字符串中删除最后一个元素来回溯

    valid_word_set = set(valid_words)
    dfs(word, valid_word_set, [])
    return result

word = "sometime"
valid_words = ["some", "time", "rome", "sometime", "so", "me"]
result = letterCombinations(word, valid_words) 
print(result)

我认为这个代码对您有用,请告诉我如果它不起作用。

英文:
def letterCombinations(word, valid_words):
      result = []

    
    def dfs(string_path, valid_word_set, curr_string):
        if not string_path:
            result.append(curr_string[:])  # Append a copy of the current string to the result list
            return
        
        for i in range(1, len(string_path) + 1):
            if string_path[:i] in valid_word_set:
                curr_string.append(string_path[:i])
                dfs(string_path[i:], valid_word_set, curr_string)
                curr_string.pop()  # Backtrack by removing the last element from the current string
    
       valid_word_set = set(valid_words)
       dfs(word, valid_word_set, [])
       return result

    word = "sometime"
    valid_words = ["some", "time", "rome", "sometime", "so", "me"]
    result = letterCombinations(word, valid_words) 
    print(result)

I think this will work for you let me know if it will not work

huangapple
  • 本文由 发表于 2023年7月31日 19:47:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803313.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定