如何高效排序食谱字典:确保食材项先于依赖它的菜品项
食谱字典的依赖排序解决方案
这个问题本质是拓扑排序场景:我们需要让每个作为食材的食谱(字典里的item)排在所有用到它的食谱前面,避免“先出现需要用到某食材的食谱,后出现该食材的食谱”的情况。
核心思路
把每个食谱item看作图的节点,若食谱A需要用到食谱B作为食材,则建立一条从B指向A的有向边(表示B必须排在A前面)。通过Kahn拓扑排序算法(高效且易实现)对节点进行排序,最终得到符合要求的顺序。
具体实现(Python示例)
def sort_recipes(recipe_dict): # 1. 收集所有需要排序的节点:仅保留属于食谱字典的item valid_nodes = set(recipe_dict.keys()) for ingredients in recipe_dict.values(): valid_nodes.intersection_update(ingredients) # 只留同时是食材的食谱item valid_nodes = list(valid_nodes) # 2. 构建入度表和邻接表 in_degree = {node: 0 for node in recipe_dict.keys()} adjacency = {node: [] for node in recipe_dict.keys()} for dish, ingredients in recipe_dict.items(): for ing in ingredients: if ing in recipe_dict: # 仅处理作为食谱的食材 adjacency[ing].append(dish) in_degree[dish] += 1 # 3. Kahn算法拓扑排序 from collections import deque queue = deque([node for node in recipe_dict.keys() if in_degree[node] == 0]) sorted_order = [] while queue: current = queue.popleft() sorted_order.append(current) for neighbor in adjacency[current]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor) # 检查循环依赖:排序后的节点数不等于总食谱数则存在环 if len(sorted_order) != len(recipe_dict): raise ValueError("食谱存在循环依赖,无法完成排序") # 按排序结果重构字典 return {node: recipe_dict[node] for node in sorted_order} # 测试示例 original_recipes = {"cake": ["egg", "sugar", "flour"], "flour": ["wheat", "titanium_dioxide"]} sorted_recipes = sort_recipes(original_recipes) print(sorted_recipes) # 输出: {'flour': ['wheat', 'titanium_dioxide'], 'cake': ['egg', 'sugar', 'flour']}
关键细节说明
- 过滤非食谱食材:比如示例中的egg、sugar不属于食谱字典的item,无需纳入排序逻辑
- 循环依赖检测:如果存在
{"A": ["B"], "B": ["A"]}这类循环依赖,算法会抛出异常,避免死循环 - 时间复杂度:O(V+E),其中V是食谱item数量,E是依赖关系总数,属于线性时间的高效算法
内容的提问来源于stack exchange,提问作者Goods
相关产品推荐
相关产品推荐

