简体   繁体   English

查找列表中两个单词之间的路径是否存在

[英]Finding if a path between two words in a list exists

I have a problem that I am trying to solve, which is, I have a list of words:我有一个要解决的问题,也就是说,我有一个单词列表:

word_list = ["DATA", "TATA", "PAPA", "PATA", "TOTO", "TITI", "TATI", "TUTO", "DARA", "DORA"]

I want to return True if a path between two words exists.如果两个单词之间存在路径,我想返回True The change from one word to another should be by replacing one char.从一个词到另一个词的变化应该是通过替换一个字符。 For instance, the paths between "DATA" and "PAPA" are:例如,“DATA”和“PAPA”之间的路径是:

DATA -> TATA -> PATA -> PAPA

DATA -> PATA -> PAPA

The code below prints all the existing paths, where I used the recursion function to do that.下面的代码打印所有现有路径,我在其中使用递归 function 来执行此操作。 How can I change it to return True|False if a path exists or not (inside find_graph_words function)?如果路径存在或不存在(在find_graph_words函数内),我如何更改它以return True|False The recursion function confuses me sometimes when I want to use return.当我想使用 return 时,递归 function 有时会让我感到困惑。

def count_diff(source, target):
    diff = 0
    for c1, c2 in zip(source, target):
        if c1 != c2:
            diff += 1
    return diff

def compute_distances(word_list):
    distances = {}
    for word in word_list:
        for target in word_list:
            if word in distances:
               maps = distances[word]
               maps[target] = count_diff(word, target)
               distances[word] = maps
            else:
               distances[word] = {target: count_diff(word, target)}
    return distances

def find_graph_words(source, target, distances, path):
    path += source + ' -> '
    to_visit = [item for item in word_list if (distances[source][item] == 1) and (item not in path)]
    if target in to_visit:
        path += target
        print(path)
    for node in to_visit:
        find_graph_words(node, target, distances, path)

if __name__ == '__main__':
    word_list = ["DATA", "TATA", "PAPA", "PATA", "TOTO", "TITI", "TATI", "TUTO", "DARA", "DORA"]
    distances = compute_distances(word_list)
    find_graph_words("DATA", "PAPA", distances, '')

In your existing code, item not in path could give wrong outcomes when shorter strings are found in longer strings (if that is possible to have in your graph).在您现有的代码中,如果在较长的字符串中发现较短的字符串(如果您的图表中可能存在),则item not in path可能会产生错误的结果。 It would be better to use a list or set structure for your path.最好为您的路径使用列表或集合结构。

For testing the existence only of a path, you can exit the loop as soon as you get a hit from recursion:为了仅测试路径的存在,您可以在递归命中后立即退出循环:

def connected(source, target, distances, path):
    to_visit = [item for item in word_list if distances[source][item] == 1 and item not in path]
    if target in to_visit:
        return True
    for node in to_visit:
        if connected(node, target, distances, path + [node]):
            return True
    return False

This can be reduced to:这可以简化为:

def connected(source, target, distances, path):
    to_visit = [item for item in word_list if distances[source][item] == 1 and item not in path]
    return target in to_visit or any(
        connected(node, target, distances, path + [node])
        for node in to_visit
    )

word_list = ["DATA", "TATA", "PAPA", "PATA", "TOTO", "TITI", "TATI", "TUTO", "DARA", "DORA"]
distances = compute_distances(word_list)
print(connected("DATA", "PAPA", distances, []))

You can improve the efficiency of determining to_visit , by creating an adjacency list first, instead of a distances matrix, where the adjacency list will only have the edges where the distance is 1.您可以通过先创建邻接表而不是距离矩阵来提高确定to_visit的效率,其中邻接表将仅包含距离为 1 的边。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM