Rust中有没有更优的方法计算数组元素的两两乘积之和?
1. 数学优化前缀和方案(性能最优,O(n) 时间复杂度,无额外依赖)
这个方案是所有实现里性能最高的,只需遍历数组一次,也不需要除法运算,避免了整数除法可能带来的边界问题:
fn sum_of_pairwise_products(arr: &[i32]) -> i32 { arr.iter() .fold((0, 0), |(total, prefix_sum), ¤t| { (total + prefix_sum * current, prefix_sum + current) }) .0 } fn main() { let a = [3, 4, 5]; assert_eq!(47, sum_of_pairwise_products(&a)); }
原理很简单:每遍历到一个元素,只需要把它和前面所有已经遍历过的元素相乘,累加到总和里即可,用前缀和就不需要重复计算前面元素的加总。
2. 平方和公式方案(代码最简洁,O(n) 时间复杂度)
利用代数公式简化计算:所有两两乘积之和 = (元素总和的平方 - 元素平方和) / 2
fn sum_of_pairwise_products(arr: &[i32]) -> i32 { let sum: i32 = arr.iter().sum(); let sum_of_squares: i32 = arr.iter().map(|&x| x * x).sum(); (sum * sum - sum_of_squares) / 2 } fn main() { let a = [3, 4, 5]; assert_eq!(47, sum_of_pairwise_products(&a)); }
注意这个方案需要确保sum * sum - sum_of_squares一定是偶数,且数值不会超出i32的取值范围,适合元素数值不大的场景。
3. 组合迭代器方案(逻辑最直观,和原始需求完全对齐)
如果你需要和原始的枚举所有两两组合的逻辑完全一致,方便后续扩展其他组合操作,可以引入itertools库的组合方法,代码可读性极高:
use itertools::Itertools; fn sum_of_pairwise_products(arr: &[i32]) -> i32 { arr.iter() .tuple_combinations::<(_, _)>() .map(|(a, b)| a * b) .sum() } fn main() { let a = [3, 4, 5]; assert_eq!(47, sum_of_pairwise_products(&a)); }
这个写法完全对应「取所有不重复的两两元素相乘再求和」的需求,不需要手动维护索引和嵌套循环,适合数组长度不大的场景。
内容的提问来源于stack exchange,提问作者kubosuke
相关产品推荐
相关产品推荐

