-
Notifications
You must be signed in to change notification settings - Fork 340
Open
Description
It would be nice to have a version of the following as a convenient, efficient library function rather than having had to roll my own:
#[inline]
fn power_multiset<T: PartialEq + Ord + Copy>(multiset: &mut Vec<T>) -> Vec<Vec<T>> {
let mut result = Vec::new();
multiset.sort_unstable(); // Sort to handle duplicates more easily
#[inline]
fn generate_subsets<T: PartialEq + Copy>(
current_subset: &mut Vec<T>,
remaining_elements: &mut Vec<T>,
all_subsets: &mut Vec<Vec<T>>,
) {
// Add the current subset to the result
all_subsets.push(current_subset.clone());
if remaining_elements.is_empty() {
return;
}
let mut i = 0;
while i < remaining_elements.len() {
let element = remaining_elements.remove(i);
current_subset.push(element);
generate_subsets(current_subset, remaining_elements, all_subsets);
// Backtrack: add the element back and remove from current_subset
current_subset.pop();
remaining_elements.insert(i, element);
// Skip duplicate elements to avoid redundant subsets
while i < remaining_elements.len() && remaining_elements[i] == element {
i += 1;
}
}
}
let mut current_subset = Vec::new();
generate_subsets(&mut current_subset, multiset, &mut result);
for subset in result.iter_mut() {
subset.sort_unstable();
}
result.sort_unstable();
result.dedup();
result
}
#[test]
fn test_power_multiset() {
let mut multiset = vec![2, 2, 3, 3, 5];
let power_multiset = power_multiset(&mut multiset);
println!("{:?}", power_multiset);
assert_eq!(power_multiset.len(), 18);
assert!(power_multiset.contains(&vec![]));
assert!(power_multiset.contains(&vec![2]));
assert!(power_multiset.contains(&vec![2, 2]));
assert!(power_multiset.contains(&vec![3]));
assert!(power_multiset.contains(&vec![2, 3]));
assert!(power_multiset.contains(&vec![2, 2, 3]));
assert!(power_multiset.contains(&vec![3, 3]));
assert!(power_multiset.contains(&vec![2, 3, 3]));
assert!(power_multiset.contains(&vec![2, 2, 3, 3]));
assert!(power_multiset.contains(&vec![5]));
assert!(power_multiset.contains(&vec![2, 5]));
assert!(power_multiset.contains(&vec![2, 2, 5]));
assert!(power_multiset.contains(&vec![3, 5]));
assert!(power_multiset.contains(&vec![2, 3, 5]));
assert!(power_multiset.contains(&vec![2, 2, 3, 5]));
assert!(power_multiset.contains(&vec![3, 3, 5]));
assert!(power_multiset.contains(&vec![2, 3, 3, 5]));
assert!(power_multiset.contains(&vec![2, 2, 3, 3, 5]));
}
Metadata
Metadata
Assignees
Labels
No labels