找到数组组合的中点

时间:2017-08-24 01:25:56

标签: arrays parallel-processing iterator rust combinations

我有一个在Rust中实现Iterator的结构(尽管问题可以应用于任何语言)来计算数组的组合。使用初始数组创建迭代器,该数组定义数组中每个条目的最大值。迭代器的实际代码仍然是一项正在进行的工作,所以可能有很多地方可以改进。

例如,如果我使用Combo函数创建Combo::new(),并且我给set_max数组[4,3,2,1],那么迭代器将生成所有组合长度为4的数组,这样任何条目都不会超过set_max中给出的条目。

因此,生成的第一个数组是[0,0,0,1],然后是[0,0,1,0][0,0,1,1][0,0,2,0][0,0,2,1][0,1,0,0],基本上,它一次增加一个条目,直到条目最大化。然后它重置它并开始一次递增两个条目。

我希望这个迭代器在某些时候实现rayon::ParallelIterator,但首先,我相信我需要一种方法将组合的计算分成两半。

如何找到迭代器的中间点,以便将其分成两部分?

在我找到这个中点后,我对实现split函数有一些想法:添加一个set_min数组,指定一个从中增加条目的起点。但问题的关键是如何找到一般的中点。

#[derive(Clone)]
pub struct Combos {
    pub set_max: Vec<usize>,
    set_current: Vec<usize>,
    size: usize,
}

impl Combos {
    pub fn new(set_max: Vec<usize>) -> Combos {
        Combos {
            set_current: vec![0; set_max.len()],
            size: set_max.iter().fold(1, |acc, x| (x + 1) * acc) - 1,
            set_max: set_max,
        }
    }

    fn increment_combo(&self, length: usize, combo: &[usize]) -> Vec<usize> {
        if let Some(last) = combo.last() {
            if *last == self.set_max[length - 1] {
                let mut v = self.increment_combo(length - 1, &combo[..length - 1]);
                v.push(0);
                return v
            } else {
                let mut v = combo.to_vec();
                v[length - 1] = last + 1;
                return v
            }
        } else {
            return Vec::new()
        }
    }
}

impl Iterator for Combos {
    type Item=Vec<usize>;

    fn next(&mut self) -> Option<Vec<usize>> {
        if self.set_current == self.set_max {
            return None
        }

        self.set_current = self.increment_combo(self.set_max.len(), &self.set_current);
        return Some(self.set_current.clone())
    }
}

1 个答案:

答案 0 :(得分:0)

只是将数组的第一个值减半的一半,因为第一个值是算法中最后一个递增的值(最重要的):

[4, 3, 2, 1]

可以这样切割:

first part:  [0, 3, 2, 1] -> [1, 3, 2, 1]
second part: [2, 3, 2, 1] -> [3, 3, 2, 1]

因此,这很容易减少一半算法:使用[2, 3, 2, 1]调用第一部分,使用[4, 3, 2, 1]调用第二部分:[2, 0, 0, 0]