在Rust中获取向量的每个子集的最简单/最惯用方法是什么?
let v = vec![1,2,3];
assert_eq!(subsets(v), [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]);
在Rust中获取向量的每个子集的最简单/最惯用方法是什么?
let v = vec![1,2,3];
assert_eq!(subsets(v), [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]);
fn powerset<T>(s: &[T]) -> Vec<Vec<T>> where T: Clone {
(0..2usize.pow(s.len() as u32)).map(|i| {
s.iter().enumerate().filter(|&(t, _)| (i >> t) % 2 == 1)
.map(|(_, element)| element.clone())
.collect()
}).collect()
}
fn main() {
let v = vec![1,2,3];
println!("{:?}", v);
let pset = powerset(&v);
println!("{:?}", pset);
}
请在此处查看其实际应用。
如果您想获取参考向量以防止复制,可以进行简单的更改:
fn powerset<T>(s: &[T]) -> Vec<Vec<&T>> {
(0..2usize.pow(s.len() as u32)).map(|i| {
s.iter().enumerate().filter(|&(t, _)| (i >> t) % 2 == 1)
.map(|(_, element)| element)
.collect()
}).collect()
}
请点击此处查看要点。
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
是可以接受的,那么您可以像这样做:从一个空集开始:[[]]
将所有元素复制到一个临时变量中,该变量将通过将第一个元素(1
)添加到每个子集来更新 -> [[1]]
并将其添加到原始向量中:[[], [1]]
对第二个元素(2
)执行步骤 2:[[], [1], [2], [1,2]]
对第三个元素(3
)执行步骤 2:[[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]]
fn powerset(s: &[i32]) -> Vec<Vec<i32>> {
let mut subsets: Vec<Vec<i32>> = vec![];
let empty: Vec<i32> = vec![];
subsets.push(empty);
let mut updated: Vec<Vec<i32>> = vec![];
for ele in s {
for mut sub in subsets.clone() {
sub.push(*ele);
updated.push(sub);
}
subsets.append(&mut updated);
}
subsets
}
fn main() {
let my_vec: Vec<i32> = vec![1,2,3];
let subs = powerset(&my_vec);
println!("{:?}", subs);
}
itertools
crate。use itertools::Itertools;
fn subsets<T: Clone>(items: Vec<T>) -> Vec<Vec<T>> {
(0..=items.len())
.map(|count| items.clone().into_iter().combinations(count))
.flatten()
.collect()
}
fn main() {
// for example ...
let it = subsets(vec![12, 24, 36]);
println!("{:?}", it);
}
combinations
的方式,它使实际逻辑保持简单。 - timlyoreturn
语句。如果您删除 return
和分号,则会将其转换为隐式返回,因此它将如下所示 https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=280506eaca8ad2a4f21b768e803b2592 - timlyo
Vec<Vec<&T>>
来避免Clone
的限制。 - Matthieu M.