1 个不稳定版本
0.1.0 | 2023年7月7日 |
---|
#2504 在 Rust 模式
19KB
225 行
迭代器的笛卡尔积
截至本文撰写之时,此crate仅提供了Hom2FCartProd
和Hom3FCartProd
类型,它们是“同质”的迭代器的二重和三重笛卡尔积,即它们产生相同类型的元素。Hom2FCartProd
的迭代器允许遍历所有不同的由原始迭代器的元素x和y组成的对[x,y]
。同样,Hom3FCartProd
允许遍历三重组[x,y,z]
。对元素的对齐顺序予以保留。
示例
use cart_prod::specs::Hom2FCartProd;
let it1 = 0..=2;
let it2 = 0..=1;
let mut it = Hom2FCartProd::new(it1, it2);
assert!(it.next() == Some([0, 0]));
assert!(it.next() == Some([0, 1]));
assert!(it.next() == Some([1, 0]));
assert!(it.next() == Some([1, 1]));
assert!(it.next() == Some([2, 0]));
assert!(it.next() == Some([2, 1]));
assert!(it.next() == None);
特性
- 支持
no_std
环境。 - 使用数组而不是元组作为笛卡尔积的元素可以在某些情况下简化并加快代码。
实现说明
不支持变长泛型
理想情况下,Hom*FCartProd
应该是CartProd
(变长)泛型类型的部分特化。然而,Rust不支持变长泛型。见https://github.com/rust-lang/rust/issues/10124。为了向前兼容,Hom2FCartProd
和Hom3FCartProd
类型定义在cart_prod::specs
模块中。
变长泛型缺失的解决方案
可以通过宏(局部)提供类型定义以及实现。然而,请注意,目前宏无法评估常量,更不用说常量表达式。见https://github.com/rust-lang/rfcs/issues/2279。由于这一点(以及时间稀缺),此类宏目前尚未提供。
不支持元组索引
与C++中的std::get
不同,在Rust中无法通过常量表达式索引元组。因此,也无法迭代迭代器元组。虽然可以利用特质对象,但由于缺少可变参数泛型,因此无法泛型地构造迭代器。
没有高性能保证
尽管实现相当高效,但并未对其性能进行基准测试或优化。虽然core::iter::Iterator::next
的实现足以实现特质,但并非实现它的最高效方式。仅重写了core::iter::Iterator::size_hint
的默认实现。
没有正确性保证
cart_prod
的实现只有几个简单的测试。如有问题,请报告问题。
替代方案
-
itertools
包提供了一个iproduct!
宏,可以用来创建迭代器的n次笛卡尔积。然而,这个宏无法检查迭代器是否同构,所以它总是会迭代元组。 -
cartesian
包提供了一个cartesian!
宏,也可以用来创建迭代器的n次笛卡尔积。然而,这个宏也无法检查迭代器是否同构,所以它总是会迭代元组。此外,在编写本文时,这个包已经有2年多没有维护了。 -
permutator
包提供了cartesian_product
、cartesian_product_cell
和cartesian_product_sync
函数,可以用来创建切片的n次笛卡尔积(而不是迭代器)。
许可证
根据您的选择,在Apache License,Version 2.0或MIT许可证下授权。除非您明确声明,否则根据Apache-2.0许可证定义的您有意提交以包含在此包中的任何贡献,都将如上所述双授权,没有任何附加条款或条件。