查找数组元素的所有唯一组合的最佳方法?

时间:2020-02-27 10:33:30

标签: arrays rust functional-programming iterator

我有一些特定整数的数组,我想找到这些整数的所有唯一组合(加法)。我敢肯定,有一种功能可以做到这一点。我试图避免在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);```

纯粹从函数式编程的角度帮助我为堕落的迭代洗礼。

编辑:在我仍在弄清楚实际可行的实现方式之前,我举了一个例子,问题更多是,我该如何解决这个更好的问题。上面的东西现在可以正常工作了(但仍然很丑!)。

2 个答案:

答案 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()

Playground

但是请注意,如果多对数字的总和相同,这可能无法为您提供真正想要的答案。例如,给定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只被计数一次?
相关问题