如何合并多条路径从头部到首次分叉前的同类型t重叠段
路径前缀合并实现方案
核心逻辑
这个需求本质是对路径的节点type序列构建前缀树,仅合并根节点到首个多分支节点的公共段,实现步骤如下:
- 按路径首节点的type值分组,首节点type不同的路径互不干涉
- 对同组内的所有路径,逐位比对节点type值,计算最长公共前缀的长度,到出现第一个type不统一的位置停止,这个位置就是首次分叉点
- 公共前缀段合并为一条,分叉后各路径保留剩余的原始节点段
Cypher 实现示例(基于Neo4j)
假设你原始查询返回的路径集合为paths,节点的type属性为t,可以直接用以下查询实现:
// 1. 预处理所有路径,提取type序列和原始路径 WITH [path IN paths | { t_seq: [n IN nodes(path) | n.t], raw_path: path }] AS path_list // 2. 按首节点type分组 UNWIND path_list AS p WITH p.t_seq[0] AS root_type, collect(p) AS same_root_paths CALL { WITH same_root_paths // 计算同组路径的最大可能前缀长度(取最短路径的节点数) WITH same_root_paths, reduce(min_len = size(same_root_paths[0].t_seq), p IN same_root_paths | CASE WHEN size(p.t_seq) < min_len THEN size(p.t_seq) ELSE min_len END ) AS max_prefix_candidate // 逐位校验,得到最长公共前缀长度 WITH same_root_paths, max_prefix_candidate, reduce(common_len = 0, i IN range(0, max_prefix_candidate - 1) | CASE WHEN all(p IN same_root_paths | p.t_seq[i] = same_root_paths[0].t_seq[i]) THEN common_len + 1 ELSE common_len END ) AS common_prefix_len // 组装合并结果 RETURN same_root_paths[0].t_seq[0..common_prefix_len] AS merged_prefix, [p IN same_root_paths | p.t_seq[common_prefix_len..]] AS branch_suffixes } // 按根节点返回最终合并结果 RETURN root_type, merged_prefix, branch_suffixes
上面的查询返回结果和你给出的示例完全匹配:
- 根节点type为1的组,公共前缀是
[1],分支后缀分别为[2,3]、[5,3] - 根节点type为2的组,公共前缀是
[2],分支后缀分别为[4,3,5]、[3,3,5]
其他场景实现
如果是在代码中做内存计算,逻辑完全一致:把路径转成type数组后按首元素分组,每组计算最长公共前缀后拆分前缀和后缀即可,也可以直接用前缀树(Trie)的实现逻辑,插入所有type序列后遍历到第一个有多个子节点的位置,前面的节点就是合并段,后面的子树直接保留原有路径。
可以学习前缀树原理、图路径聚合计算相关内容深入了解这类需求的通用实现。
内容的提问来源于stack exchange,提问作者picklepick
相关产品推荐
相关产品推荐

