如何检查四个浮点数值范围之间不存在重叠?
浮点数值范围的无重叠检查方案
核心最优方案:排序后验证相邻范围
针对多个浮点范围的重叠检查,先排序再验证相邻范围是比逐一两两对比更高效的实现方式(时间复杂度从O(n²)降至O(n log n)),逻辑也更简洁清晰:
- 先校验单个范围有效性:确保每个输入的范围满足「下限 ≤ 上限」,否则直接判定输入无效。
- 按范围下限从小到大排序:排序后,只要所有相邻范围都不重叠,整个集合的范围就不会存在任何交叉——因为排序后前面范围的下限必然≤后面范围的下限,若前面范围的上限≤后面范围的下限,非相邻范围自然不会产生重叠。
- 检查相邻范围是否重叠:对于排序后的两个相邻范围
prev(min: pMin, max: pMax)和curr(min: cMin, max: cMax),只要pMax < cMin(考虑浮点精度可添加极小误差阈值),就说明二者不重叠;反之则存在重叠。
Swift 代码实现示例
// 定义浮点范围结构体 struct FloatRange { var min: Double var max: Double // 验证单个范围是否合法 var isValid: Bool { min <= max } } // 检查一组浮点范围是否无重叠 func areRangesNonOverlapping(_ ranges: [FloatRange]) -> Bool { // 过滤并检查无效范围 let validRanges = ranges.filter { $0.isValid } guard validRanges.count == ranges.count else { print("存在无效范围(下限大于上限)") return false } // 按范围下限排序 let sortedRanges = validRanges.sorted { $0.min < $1.min } // 遍历验证相邻范围 for i in 1..<sortedRanges.count { let prevRange = sortedRanges[i-1] let currRange = sortedRanges[i] // 引入epsilon处理浮点精度误差,可根据业务调整精度 let epsilon = 1e-9 if prevRange.max >= currRange.min - epsilon { return false } } return true } // 测试用例 let validRanges = [ FloatRange(min: 0.0, max: 2.5), FloatRange(min: 3.0, max: 5.0), FloatRange(min: 6.0, max: 8.0), FloatRange(min: 9.0, max: 10.0) ] print(areRangesNonOverlapping(validRanges)) // 输出 true let overlappingRanges = [ FloatRange(min: 0.0, max: 3.0), FloatRange(min: 2.5, max: 5.0) ] print(areRangesNonOverlapping(overlappingRanges)) // 输出 false
关于逐一检查的补充
如果范围数量极少(比如仅4个),逐一两两对比的方式也能实现,但代码冗余度更高,且当范围数量增加时效率会明显下降。其逻辑是:遍历每一个范围,与其他所有范围对比是否重叠,只要发现任意一对重叠就返回false。
注意浮点精度问题
由于浮点数存在精度误差,直接使用严格的</>判断可能出现误判(比如本应刚好衔接的两个范围,因精度问题被判定为重叠)。建议引入极小的epsilon值(如1e-9),在判断时允许微小的精度误差,具体数值可根据业务场景调整。
内容的提问来源于stack exchange,提问作者psb
相关产品推荐
相关产品推荐

