You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于任务双属性构建层级列表及查找父任务的技术问询

嘿,我来给你捋清楚这个任务依赖链的实现方案,咱们从需求到代码一步步拆解,保证清晰易懂:

核心需求拆解

首先得明确咱们要解决的问题:手里的quests数据是无序存储的,规则是当A任务结束时,会授予B任务。我们需要:

  • 找到起始任务:没有任何任务能解锁它,是链条的起点
  • 找到最终任务:它结束后不会解锁任何任务,是链条的终点
  • 梳理出完整的任务触发链
  • 确定每个任务的父任务(也就是解锁它的那个任务)
技术实现步骤

1. 构建快速映射表

首先用两个字典(哈希表)把任务间的关联关系存起来,这样后续查找效率拉满:

  • endToGrantMap:键是结束的任务ID(questEndID),值是被授予的任务ID(questGrantID)——用来快速查“某个任务结束后会解锁谁”
  • grantToEndMap:键是被授予的任务ID(questGrantID),值是触发它的结束任务ID(questEndID)——用来快速查“某个任务是被谁解锁的”

用C#实现的代码示例(对应你给出的任务类):

// 模拟示例数据
var questsList = new List<quests>
{
    new quests { questGrantID = "quest234", questEndID = "quest567" },
    new quests { questGrantID = "quest987", questEndID = "quest234" },
    new quests { questGrantID = "quest654", questEndID = "quest987" }
};

// 初始化映射字典
Dictionary<string, string> endToGrantMap = new Dictionary<string, string>();
Dictionary<string, string> grantToEndMap = new Dictionary<string, string>();

foreach (var quest in questsList)
{
    endToGrantMap[quest.questEndID] = quest.questGrantID;
    grantToEndMap[quest.questGrantID] = quest.questEndID;
}

2. 定位起始/最终任务

  • 起始任务:找不到任何任务能解锁它(也就是它的ID不在endToGrantMap的键里,因为没有任务结束会授予它)
  • 最终任务:它结束后不会解锁任何任务(也就是它的ID不在grantToEndMap的键里,因为它不是任何任务的授予触发源)

代码示例:

// 找起始任务
string startQuest = questsList.Select(q => q.questGrantID)
                              .First(id => !endToGrantMap.ContainsKey(id));
// 示例里结果是 quest654

// 找最终任务
string endQuest = questsList.Select(q => q.questEndID)
                            .First(id => !grantToEndMap.ContainsKey(id));
// 示例里结果是 quest567

3. 构建完整任务链

从起始任务出发,顺着grantToEndMap就能遍历出完整的触发顺序:

List<string> fullQuestChain = new List<string>();
string currentQuest = startQuest;

// 遍历所有有后续的任务
while (currentQuest != null)
{
    fullQuestChain.Add(currentQuest);
    grantToEndMap.TryGetValue(currentQuest, out currentQuest);
}
// 加上最终任务
fullQuestChain.Add(endQuest);

// 示例里的结果就是:["quest654", "quest987", "quest234", "quest567"]

4. 生成父任务映射

如果需要单独存储每个任务的父任务(解锁它的任务),可以直接用字典存储:

Dictionary<string, string> parentQuestMap = new Dictionary<string, string>();
foreach (var quest in questsList)
{
    // 规则:questEndID结束 → 授予questGrantID,所以questGrantID的父任务是questEndID
    parentQuestMap[quest.questGrantID] = quest.questEndID;
}

// 示例里:
// parentQuestMap["quest234"] = "quest567"
// parentQuestMap["quest987"] = "quest234"
// parentQuestMap["quest654"] = "quest987"
扩展:处理多分支场景

如果遇到一个任务结束后授予多个任务,或者存在多条独立任务链的情况,只需要把字典的 value 改成列表即可:
比如用Dictionary<string, List<string>> endToGrantsMap来存储一个任务对应的多个被授予任务,后续遍历逻辑稍作调整就能兼容。

总结

整个方案的核心就是用哈希表快速建立任务间的关联,避免低效的遍历查找,时间复杂度是O(n),不管任务数据量多大都能高效处理。

内容的提问来源于stack exchange,提问作者strykstaguy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:45:06