在元组列表中删除中间对

发布于 2025-02-11 19:41:12 字数 289 浏览 2 评论 0原文

给定一个元素列表,例如

[(0,1),(0,2),(0,3),(1,4),(1,5),(2,6),(6,7),(6,7),( [7,8)]

这形成了一种树,其中0个有3个孩子,1个有2个孩子,依此类推。我们还看到0 - > 2 - > 6-> 7 - > 8创建了这个曲折的分支。我如何删除所有这些笔直的分支,以便以这样的输出结尾:

[(0,1),(0,8),(0,3),(1,4),(1,5),

如果他们是1和孩子之间的节点,然后如果该节点没有孩子的孩子,就直接与孩子链接。

Given a list of tuples like

[(0,1), (0,2), (0,3), (1,4), (1,5), (2,6), (6,7), (7,8)]

this forms a kind of a tree, where 0 has 3 children, 1 has 2 children and so on. We also see that 0 -> 2 -> 6 -> 7 -> 8 creates this striaght branch. How can i remove all such straight branches so that i end with an output like:

[(0,1), (0,8), (0,3), (1,4), (1,5)]

similarily if their was a node between 1 and its children, then just directly linking to its children if that node did not have children of itself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘴硬脾气大 2025-02-18 19:41:12

我将使用Python代码回答。

这个想法是首先创建一个邻接列表,其中每个节点键都有一个词典,上面有一个带有节点子的键的列表。

然后使用后订单遍历,其中每个恰好一个孩子的节点都会从链中取出。

最后,将邻接列表转换回边缘列表。

代码:

from collections import defaultdict

# create adjacency list as dict(int, List<int>)
def create_graph(edges):
    adj = defaultdict(list)
    for a, b in edges:
        adj[a].append(b)
    return adj
    
# Perform depth-first traversal to remove nodes
# that have exactly one child
def remove_lonely_nodes(adj, nodeid):
    adj[nodeid] = [remove_lonely_nodes(adj, child) for child in adj[nodeid]]
    if len(adj[nodeid]) == 1:  # skip nodeid
        return adj[nodeid][0]
    return nodeid

def getedges(adj, nodeid):
    return [
        (nodeid, childid) for childid in adj[nodeid]
    ] + [
       edge for id in adj[nodeid] 
            for edge in getedges(adj, id)
    ]

示例运行

edges = [(0,1), (0,2), (0,3), (1,4), (1,5), (2,6), (6,7), (7,8)]
adj = create_graph(edges)
remove_lonely_nodes(adj, 0)  # we assume 0 is the root
edges = getedges(adj, 0)
print(edges)  # [(0, 1), (0, 8), (0, 3), (1, 4), (1, 5)]

I'll answer this with Python code.

The idea is to first create an adjacency list, where for each node key, a dictionary has a list with keys of the node's children.

Then use a post-order traversal, where every node that has exactly one child is taken out of the chain.

Finally, convert that adjacency list back to a list of edges.

code:

from collections import defaultdict

# create adjacency list as dict(int, List<int>)
def create_graph(edges):
    adj = defaultdict(list)
    for a, b in edges:
        adj[a].append(b)
    return adj
    
# Perform depth-first traversal to remove nodes
# that have exactly one child
def remove_lonely_nodes(adj, nodeid):
    adj[nodeid] = [remove_lonely_nodes(adj, child) for child in adj[nodeid]]
    if len(adj[nodeid]) == 1:  # skip nodeid
        return adj[nodeid][0]
    return nodeid

def getedges(adj, nodeid):
    return [
        (nodeid, childid) for childid in adj[nodeid]
    ] + [
       edge for id in adj[nodeid] 
            for edge in getedges(adj, id)
    ]

Example run

edges = [(0,1), (0,2), (0,3), (1,4), (1,5), (2,6), (6,7), (7,8)]
adj = create_graph(edges)
remove_lonely_nodes(adj, 0)  # we assume 0 is the root
edges = getedges(adj, 0)
print(edges)  # [(0, 1), (0, 8), (0, 3), (1, 4), (1, 5)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文