如何高效从Vector3列表中按X、Z分组筛选Y值最大的向量?
高效筛选X/Z相同组中Y值最大的Vector3元素
嘿,这个嵌套循环的方案在数据量上去之后确实会拉胯,尤其是在性能敏感的代码段里,必须换个更高效的路子。下面给你两个最优的优化方案,直接把时间复杂度从O(n²)降到O(n)或者O(n log n),完美适配你的需求:
方法一:字典分组(最优性能,O(n) 时间复杂度)
核心思路是把X和Z作为分组唯一键,只遍历原列表一次,每个分组里始终保留Y值最大的Vector3。
C# 代码示例
// 用ValueTuple存储X和Z作为字典键,自动实现相等判断 var groupDict = new Dictionary<(float X, float Z), Vector3>(); foreach (var vec in MyList) { var key = (vec.X, vec.Z); // 若键不存在,或当前向量的Y值更大,则更新字典中的对应值 if (!groupDict.ContainsKey(key) || vec.Y > groupDict[key].Y) { groupDict[key] = vec; } } // 字典的值集合就是最终筛选结果 List<Vector3> result = groupDict.Values.ToList();
注意事项
如果你的Vector3的X/Z是浮点数,要考虑精度误差问题——比如本该相等的X/Z可能因浮点精度被判定为不等。遇到这种情况,可以先将X/Z四舍五入到指定精度(比如保留2位小数)再作为键,或者自定义字典的相等比较器。
方法二:排序后去重(O(n log n) 时间复杂度)
如果不想用字典,也可以先按规则排序,再遍历一次筛选出每个分组的第一个元素(也就是Y值最大的那个)。
C# 代码示例
// 按X升序、Z升序、Y降序排序,确保同组内Y最大的元素排在最前面 var sortedList = MyList.OrderBy(v => v.X) .ThenBy(v => v.Z) .ThenByDescending(v => v.Y) .ToList(); List<Vector3> result = new List<Vector3>(); (float lastX, float lastZ) = (float.NaN, float.NaN); foreach (var vec in sortedList) { // 当X/Z与上一个元素不同时,说明是新分组的第一个(Y最大)元素 if (vec.X != lastX || vec.Z != lastZ) { result.Add(vec); (lastX, lastZ) = (vec.X, vec.Z); } }
验证示例输入
针对你给出的示例输入:(1,1,1) (1,2,1) (1,4,1) (2,3,2) (2,5,2) (1,4,2) (1,2,2) (1,1,2) (2,5,1) (2,4,1) (2,9,1)
两种方法都会得到预期输出:(1,4,1) (2,5,2) (1,4,2) (2,9,1)
内容的提问来源于stack exchange,提问作者Azeranth
相关产品推荐
相关产品推荐

