我有一些特定整数的数组,我想找到这些整数的所有唯一组合(加法)。我敢肯定,有一种功能可以做到这一点。我试图避免在for循环内推for循环的迭代方法。在这种情况下,我正在使用Rust,但是这个问题通常是一个“函数式编程,怎么办?”采取。
我的第一个想法是,我应该将v
中的每个条目与其他所有条目一起压缩,通过添加单个元素来减少它们,并过滤重复项。这是O(| v | ^ 2),感觉很糟糕,这意味着我可能会错过一些对功能高手孩子来说相当明显的东西。而且我什至不知道该怎么做,我可能会使用for循环来构造新的大规模数组。
我的第一遍:请注意v
拥有我关心的所有数字。
let mut massive_arr = Vec::new();
for &elem in v.iter(){
for &elem2 in v.iter(){
massive_arr.push((elem,elem2));
}
}
let mut single_massive = Vec::new();
for &tuple in massive_arr.iter(){
single_massive.push(tuple.0 + tuple.1);
}
single_massive.dedup();
let summand: usize = single_massive.iter().sum(); println!("The sum of all that junk is {:?}", summand);```
纯粹从函数式编程的角度帮助我为堕落的迭代洗礼。
编辑:在我仍在弄清楚实际可行的实现方式之前,我举了一个例子,问题更多是,我该如何解决这个更好的问题。上面的东西现在可以正常工作了(但仍然很丑!)。
答案 0 :(得分:1)
您可以使用itertools(我手边没有编译器,但您可能会明白):
use itertools::Itertools;
iproduct!(v.iter(), v.iter()) // construct all pairs
.map(|tuple| tuple.0+tuple.1) // sum each pair
.unique() // de-duplicate (uses a HashMap internally)
.sum() // sum up
所有这些仍然是O(n ^ 2),据我所知,这是渐近最优的,因为可能需要所有成对的数字。
为避免明显的重复,可以使用tuple_combinations
:
v.iter()
.tuple_combinations()
.map(|(a, b)| a+b)
.unique()
.sum()
答案 1 :(得分:1)
改进@phimuemue的答案,可以避免出现类似以下的明显重复项:
v.iter()
.enumerate()
.flat_map (|(i, a)| v[i+1..].iter().map (move |b| a+b))
.unique() // May not be needed or what you really want, see note below
.sum()
但是请注意,如果多对数字的总和相同,这可能无法为您提供真正想要的答案。例如,给定vec![1, 2, 3, 4]
作为输入,您期望:
(1+2) + (1+3) + (1+4) + (2+3) + (2+4) + (3+4) = 30
3 + 4 + 5 + 6 + 7 = 25
,因为1+4 == 2+3 == 5
只被计数一次?