Rust中如何用整数匹配数值映射范围?求最简实现方案
嘿,这个问题挺常见的——当你有一堆对应数值范围的键值对,想用一个整数快速找到它所属范围对应的值对吧?在Rust里,最简的实现方式得看你的数据规模,我给你两种实用的方案,从简单直接到高效优化都覆盖到了:
最简实现方案
1. 小数据集:线性遍历(零依赖最省心)
如果你的范围数量不多(比如几十个以内),直接用数组存范围和对应值,然后遍历查找是最省心的选择——代码量少、逻辑直观,还不需要任何第三方依赖。
比如我们先定义一个可读性好的范围结构体,再写个简单的查找函数:
#[derive(Debug)] struct RangeMap<T> { start: i32, end: i32, value: T, } impl<T> RangeMap<T> { // 判断数值是否在当前范围内 fn contains(&self, num: i32) -> bool { num >= self.start && num <= self.end } } // 遍历查找匹配的范围值 fn find_value<T>(range_maps: &[RangeMap<T>], num: i32) -> Option<&T> { range_maps.iter() .find(|rm| rm.contains(num)) .map(|rm| &rm.value) } fn main() { let ranges = vec![ RangeMap { start: 0, end: 10, value: "低区间" }, RangeMap { start: 11, end: 20, value: "中区间" }, RangeMap { start: 21, end: 30, value: "高区间" }, ]; println!("{:?}", find_value(&ranges, 5)); // 输出: Some("低区间") println!("{:?}", find_value(&ranges, 15)); // 输出: Some("中区间") println!("{:?}", find_value(&ranges, 35)); // 输出: None }
2. 大数据集:二分查找(高效优化)
如果你的范围数量很多(几百上千个),线性遍历就有点慢了。这时候可以把范围按start排序,用二分查找快速定位,时间复杂度直接降到O(log n)。
核心思路是:找到第一个start大于目标数的范围,然后往前推一个,检查这个范围是否包含目标数即可(前提是你的范围是互斥不重叠的,这也是这类场景的常规情况):
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] struct RangeMap<T> { start: i32, end: i32, value: T, } fn find_value<T>(sorted_ranges: &[RangeMap<T>], num: i32) -> Option<&T> { // 找到第一个start > num的位置 let idx = sorted_ranges.binary_search_by_key(&num, |rm| rm.start) .unwrap_or_else(|x| x); // 往前取一个范围,检查是否包含当前数值 idx.checked_sub(1) .and_then(|i| sorted_ranges.get(i)) .filter(|rm| num <= rm.end) .map(|rm| &rm.value) } fn main() { // 注意:范围必须先按start从小到大排序! let mut ranges = vec![ RangeMap { start: 21, end: 30, value: "高区间" }, RangeMap { start: 0, end: 10, value: "低区间" }, RangeMap { start: 11, end: 20, value: "中区间" }, ]; ranges.sort(); // 先完成排序 println!("{:?}", find_value(&ranges, 5)); // 输出: Some("低区间") println!("{:?}", find_value(&ranges, 15)); // 输出: Some("中区间") println!("{:?}", find_value(&ranges, 35)); // 输出: None }
额外小提示
如果不想自己写二分逻辑,也可以用intervaltree这类专门处理区间查找的crates,但如果追求“最简”,自己写线性遍历或二分查找其实更轻量——毕竟不需要引入额外依赖。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

