Rust中如何对数组分块求和并将当前块与前一块的和进行比较
Rust 相邻滑动分块求和与比较实现
直接用Rust切片自带的windows重叠滑动窗口API就能实现需求,不需要手动计算偏移遍历数组,实现简洁且性能有标准库保障。
核心实现逻辑
- 若数组后续没有修改元素的需求,可以去掉定义时的
mut关键字,减少不必要的可变性;如果有修改元素的需求保留mut也不影响窗口逻辑。 - 调用
arr.windows(窗口大小)可以拿到所有固定长度的连续重叠滑动窗口迭代器,窗口大小传3时,迭代器会依次产出&[100,200,300]、&[200,300,400]这类对应分块的切片。 - 对每个窗口调用
iter().sum()即可快速计算分块和,不需要手动写循环累加。 - 相邻分块的比较可以先收集所有窗口和再遍历对比,也可以边计算窗口和边对比,后者不需要额外存储所有窗口和,内存占用更低,适合超长数组场景。
基础实现代码(无外部依赖)
fn main() { // 无修改需求可以去掉mut let arr = vec![100, 200, 300, 400, 500, 600]; const WINDOW_SIZE: usize = 3; // 边界校验:数组长度至少要比窗口大小大1,才能凑出2个相邻可比较的窗口 if arr.len() < WINDOW_SIZE + 1 { println!("数组长度不足,无法生成相邻滑动分块"); return; } // 计算所有滑动窗口的和 let window_sums: Vec<i32> = arr .windows(WINDOW_SIZE) .map(|chunk| chunk.iter().sum()) .collect(); // 逐对比较相邻窗口的和 for (pair_idx, (sum_a, sum_b)) in window_sums.iter().zip(window_sums.iter().skip(1)).enumerate() { let chunk_a_pos = pair_idx; let chunk_b_pos = pair_idx + 1; match sum_a.cmp(sum_b) { std::cmp::Ordering::Greater => println!("分块{}和为{},大于相邻分块{}的和{}", chunk_a_pos, sum_a, chunk_b_pos, sum_b), std::cmp::Ordering::Less => println!("分块{}和为{},小于相邻分块{}的和{}", chunk_a_pos, sum_a, chunk_b_pos, sum_b), std::cmp::Ordering::Equal => println!("分块{}和为{},等于相邻分块{}的和{}", chunk_a_pos, sum_a, chunk_b_pos, sum_b), } } }
运行后第一组输出就对应你举例的chunkA、chunkB比较场景:
分块0和为600,小于相邻分块1的和900
分块1和为900,小于相邻分块2的和1200
分块2和为1200,小于相邻分块3的和1500
低内存优化版本
如果数组长度极大,不想额外分配内存存储所有窗口和,可以边计算边比较,空间复杂度从O(n)降到O(1):
fn main() { let arr = vec![100, 200, 300, 400, 500, 600]; const WINDOW_SIZE: usize = 3; if arr.len() < WINDOW_SIZE + 1 { println!("数组长度不足"); return; } let mut window_iter = arr.windows(WINDOW_SIZE).map(|chunk| chunk.iter().sum::<i32>()); // 先取第一个窗口的和作为初始前序值 let mut prev_sum = window_iter.next().unwrap(); for (pair_idx, curr_sum) in window_iter.enumerate() { let chunk_a_pos = pair_idx; let chunk_b_pos = pair_idx + 1; let compare_result = if prev_sum > curr_sum { "前者更大" } else if prev_sum < curr_sum { "后者更大" } else { "两者相等" }; println!("分块{}(和{})与分块{}(和{})比较结果:{}", chunk_a_pos, prev_sum, chunk_b_pos, curr_sum, compare_result); prev_sum = curr_sum; } }
注意事项
- 不要把
windows和chunks方法搞混:windows生成的是重叠滑动窗口,刚好匹配相邻分块共享窗口大小-1个元素的需求;chunks生成的是不重叠的独立分块,不符合当前场景。 - 如果数组元素是u32、i64等其他数值类型,替换
sum后的泛型参数为对应类型即可,避免类型推导失败。 - 必须做边界长度校验:当数组长度小于窗口大小时
windows会返回空迭代器,长度刚好等于窗口大小时仅能生成1个分块,两种情况都无法做相邻比较,直接取值会触发panic。
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

