algorithm - 如何将集合的元素分组为N个部分的所有组合?

标签 algorithm rust vec

我遇到了一个看起来很简单但实际上却很困难的问题。它似乎是组合算法的子集。有更快,更直接的算法吗?

/// split the group {v1} to {n} parts
///
/// For example:
///  Group(here represented by an array):
///   [1, 2, 3, 4]
///  split Group to 2 part, got:
///   [[1], [2, 3, 4]]
///   [[1, 2], [3, 4]]
///   [[1, 3], [2, 4]]
///   [[1, 4], [2, 3]]
///   [[1, 2, 3], [4]]
fn split_group(v1: Vec<i32>, n: i32) -> Vec<Vec<Vec<i32>>> {
    unimplemented!()
}

fn main() {
    let mut v1 = vec![1, 2, 3, 4];
    let v2 = split_group(v1, 2);
    assert_eq!(
        v2,
        vec![
            vec![vec![1], vec![2, 3, 4]],
            vec![vec![1, 2], vec![3, 4]],
            vec![vec![1, 3], vec![2, 4]],
            vec![vec![1, 4], vec![2, 3]],
            vec![vec![1, 2, 3], vec![4]],
        ]
    );
}

最佳答案

这是从@MBo链接的this answer派生的解决方案。
递归函数用N个值填充K个零件。lastfilled参数有助于避免重复-它提供了每个部分中前导(最小)元素的递增顺序。empty参数旨在避免出现空的部分。

use std::cmp;

pub fn genp(parts: &mut Vec<Vec<usize>>, mut empty: usize, n: usize, k: usize, m: usize, lastfilled: Option<usize>) {
    if m == n {
        return println!("{:?}", parts);
    }
    let mut start = 0;
    if n - m == empty {
        start = k - empty;
    }
    let max = match lastfilled {
        None => 1,
        Some(lastfilled) => lastfilled + 2,
    };
    for i in start..cmp::min(k, max) {
        parts[i].push(m);
        if parts[i].len() == 1 {
            empty -= 1;
        }
        genp(parts, empty, n, k, m+1, cmp::max(Some(i), lastfilled));
        parts[i].pop();
        if parts[i].is_empty() {
            empty += 1;
        }
    }
}

pub fn split_group(v1: Vec<i32>, k: usize) {
    let mut parts: Vec<Vec<usize>> = Vec::new();
    for _ in 0..k {
        parts.push(Vec::new());
    }
    genp(&mut parts, k, v1.len(), k, 0, None);
}
fn main() {
    let v1 = vec![1, 2, 3, 4];
    split_group(v1, 2);
}

[[0, 1, 2], [3]]
[[0, 1, 3], [2]]
[[0, 1], [2, 3]]
[[0, 2, 3], [1]]
[[0, 2], [1, 3]]
[[0, 3], [1, 2]]
[[0], [1, 2, 3]]

关于algorithm - 如何将集合的元素分组为N个部分的所有组合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64862204/

相关文章:

python-3.x - 错误的合并排序实现

algorithm - 如何存储一组可变项目 `(t, p)`,以便对某些 `k` 最小化 `(n-t)*p` 的 `n` 项目进行查询是有效的?

rust - 我可以在宏中解串文字吗?

string - 将文件按行然后按单词分割时,为什么会得到一个空向量?

algorithm - 机器人在网格算法中移动可能的路径和时间复杂度?

c - 存储压缩集的最佳方式

rust - 在 Rust 中实现链表时如何复制原始指针?

rust - 使用图像箱时如何获得 u8 RGB 值的向量?

generics - 收集到Vec与&Vec

rust - 为什么 Rust 的 ChunksExact<T> 没有在编译时已知的大小