3个版本 (重大更改)
0.3.0 | 2024年3月19日 |
---|---|
0.2.0 | 2023年12月15日 |
0.1.0 | 2023年12月15日 |
#575 in 算法
每月下载 27次
47KB
796 行
prime bag
使用无符号整数进行存储的包数据类型。这是通过为每个可能的物品分配一个素数来实现的。包的内容由这些素数的乘积表示。如果可能的物品集合受限制,并且某些物品比其他物品更常见,则这种方法效果最好。为了最大化包的可能大小,将较小的素数分配给更常见的物品。
使用素数包,某些操作可以非常高效地进行:添加元素或合并两个包是通过乘法实现的。移除元素或元素包是通过除法实现的。检查元素是否存在是通过取模实现的。
集合操作 | 数学操作 |
---|---|
插入 / 扩展 | 乘法 |
移除 | 除法 |
包含 / 超集 | 取模 |
交集 | 最大公约数 |
包中的元素必须实现 PrimeBagElement
入门
use prime_bag::*;
#[derive(Debug)]
pub struct MyElement(usize);
impl PrimeBagElement for MyElement {
fn into_prime_index(&self) -> usize {
self.0
}
fn from_prime_index(value: usize) -> Self {
Self(value)
}
}
fn main() {
let bag = PrimeBag16::<MyElement>::try_from_iter([MyElement(1), MyElement(2), MyElement(2)]).unwrap();
let bag2 = bag.try_extend([MyElement(3), MyElement(3), MyElement(3)]).unwrap();
let items : Vec<(MyElement, core::num::NonZeroUsize)> = bag2.iter_groups().collect();
let inner_items: Vec<(usize, usize)> = items.into_iter().map(|(element, count)|(element.0, count.get())).collect();
assert_eq!(inner_items, vec![(1,1), (2,2), (3,3)])
}
每个元素使用的位数
索引 | 素数 | 使用的位数 | 128位素数包的容量 |
---|---|---|---|
0 | 2 | 1.00 | 128 |
1 | 3 | 1.58 | 80 |
2 | 5 | 2.32 | 55 |
3 | 7 | 2.81 | 45 |
4 | 11 | 3.46 | 37 |
5 | 13 | 3.70 | 34 |
6 | 17 | 4.09 | 31 |
7 | 19 | 4.25 | 30 |
8 | 23 | 4.52 | 28 |
9 | 29 | 4.86 | 26 |
10 | 31 | 4.95 | 25 |
11 | 37 | 5.21 | 24 |
14 | 47 | 5.55 | 23 |
15 | 53 | 5.73 | 22 |
18 | 67 | 6.07 | 21 |
22 | 83 | 6.38 | 20 |
26 | 103 | 6.69 | 19 |
32 | 137 | 7.10 | 18 |
41 | 181 | 7.50 | 17 |
53 | 251 | 7.97 | 16 |
72 | 367 | 8.52 | 15 |
102 | 563 | 9.14 | 14 |
156 | 919 | 9.84 | 13 |
255 | 1619 | 10.66 | 12 |
依赖项
~54KB