【发布时间】:2020-05-13 07:43:22
【问题描述】:
我正在使用Vec 来存储二维(行主要)值矩阵。我想用一个滑动的 2D 子窗口迭代这个矩阵来应用一个过滤器(不幸的是它是不可分离的)。
我在 slice 文档中看到存在 windows 函数,这是我想要的,但是是二维的。
我想过将其实现为:
fn main() {
// 4 rows 3 columns
let dim: (usize, usize) = (4, 3);
// Place-holder matrix
#[rustfmt::skip]
let mat = vec![0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11];
// 2D index to 1D index
let linearize = |r, c| r * dim.1 + c;
// The dimensions of my sub-window
let win_size: usize = 2;
// Calculate the bounds for which the top left corner of each window may exist
let bounds: (usize, usize) = (dim.0 - win_size + 1, dim.1 - win_size + 1);
// Convert window 1D index into a 2D index
let split = |i| (i / win_size, i % win_size);
// Iterate over all the top left corners
let window_2d = (0..bounds.0 * bounds.1).map(|i| {
// Get the 2D index of the top left corner
let (r, c) = (i / bounds.1, i % bounds.1);
// Borrow the matrix, so our closure may own the reference
let bmat = &mat;
// Return an iterator for this window
return (0..win_size * win_size).map(move |x| {
let (wr, wc) = split(x);
return bmat[linearize(wr + r, wc + c)];
});
});
// Print the windows out
window_2d.for_each(|it| {
print!("[ ");
it.for_each(|x| print!("{} ", x));
println!("]");
});
}
本质上是在一系列索引上创建一个迭代器,然后映射到矩阵的方括号运算符。 据我所知,这将对迭代器的每个 deref 进行边界检查。
我想知道是否有替代方案可以省略边界检查?也许使用chunks、windows 和zip 的组合,将矩阵分块成行,每行都有一个滑动窗口,然后压缩行的窗口并将结果展平?
谢谢!
编辑:
我不想简单地迭代 2D 数组,我想在数组上滑动 2D 窗口,类似于 std::slice::windows 函数的工作原理。
【问题讨论】:
-
...Iterate over two-dimensional Vector of Options; Rust efficiently chunk large vector into a vector of vectors。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。
-
@Shepmaster 感谢您的回复,我已经编辑了问题。您的链接问题都没有真正回答我的问题。您链接的This 很接近,但仍未得到答复,我相信我的问题可以更好地说明这个问题。