统计嵌套结构内值出现次数并更新结构的高性能实现方案
最优实现方案
核心思路采用「先全局统计、再批量赋值」的两阶段实现,时间复杂度为线性O(n),是当前场景下性能最高的方案。
方案优势
- 仅需两轮全量遍历,总操作次数仅为10万次(5000条主结构 * 10个子结构 * 2轮遍历),无冗余计算
- 字典读写均为均摊O(1)复杂度,统计效率极高
- 逻辑清晰无复杂判断,出错概率远低于边遍历边计数的实现
实现代码
// 第一步:全局统计每个位置+值的出现次数 // 用(子结构索引, 值)作为统计维度,符合按位置统计的需求 var countDict = new Dictionary<(int subIndex, string subValue), int>(); for (int i = 0; i < allStructures.Count; i++) { var subList = allStructures[i].subStructure; for (int j = 0; j < subList.Count; j++) { var key = (j, subList[j].value); countDict[key] = countDict.TryGetValue(key, out int count) ? count + 1 : 1; } } // 第二步:批量赋值occurrences属性 for (int i = 0; i < allStructures.Count; i++) { var subList = allStructures[i].subStructure; for (int j = 0; j < subList.Count; j++) { var currentSub = subList[j]; currentSub.occurrences = countDict[(j, currentSub.value)]; } }
兼容说明
如果使用不支持值元组的低版本.NET框架,可以将key替换为字符串拼接形式string key = $"{j}_{subList[j].value}",性能差异极小。如果后续子结构的排列顺序可能调整,也可以将统计key替换为(sub.name, sub.value),适配性更强,性能损失可以忽略。
原有思路问题
如果采用边遍历边统计的逻辑,每次遇到新值都需要遍历全量列表计算次数,时间复杂度会达到O(n²),最坏情况下总操作次数可达25亿次,性能差距非常明显。即使添加了已计算项跳过的判断,也需要额外的哈希存储来标记已计算项,开销远高于两次线性遍历的方案。
内容的提问来源于stack exchange,提问作者dcaping
相关产品推荐
相关产品推荐

