我正在编写一个函数来计算Rust中Vec<Vec<isize>>
的{{3}},而无需使用任何外部包装箱。我正在尝试尽可能地习惯地做到这一点,但是我遇到了一些错误处理的障碍。
基本上我要做的就是在Wikipedia页面上提到:
总面积表可以一次有效地计算 在图像上方,因为(x,y)的总面积表中的值为 只是:
其中
i
提供网格中的值,I
提供先前的值 表的计算值。显然,如果x或y为0,则某些 这些将不存在,在这种情况下,将它们替换为0
。
但是,值得注意的是,如果I(x,y - 1)
即使存在y - 1
也不存在,那么我们正在使用的网格实际上是非矩形的,我们想返回一个在这种情况下,NonRectError
。
在所有这些背景下,下面是代码:我需要防止减法引起的溢出错误,并在特殊情况下返回NonRectError
:
fn compute_summed_area_table(grid: &Vec<Vec<isize>>) -> Result<Vec<Vec<isize>>,NonRectError> {
let mut summed_area_table =
vec![Vec::with_capacity(grid[0].len()); grid.len()];
for (yi,row) in grid.iter().enumerate() {
for (xi,&value) in row.iter().enumerate() {
let (prev_row,prev_column_idx) = (
yi.checked_sub(1).and_then(|i| summed_area_table.get(i)),xi.checked_sub(1)
);
let summed_values =
value +
// I(x,y - 1)
match prev_row {
None => &0,Some(prev_row_vec) => match prev_row_vec.get(xi) {
Some(v) => v,None => return Err(NonRectError { xi,yi })
}
} +
// I(x - 1,y)
(prev_column_idx
.and_then(|i| summed_area_table[yi].get(i))
.unwrap_or(&0)) -
// I(x - 1,y - 1)
(prev_row
.map_or(&0,|r| {
prev_column_idx
.and_then(|i| r.get(i))
.unwrap_or(&0)
}));
summed_area_table[yi].push(summed_values);
}
}
Ok(summed_area_table)
}
// Omitted the definition of NonRectError here,but it is defined.
这段代码显然是sin本身的定义,但是我不确定从哪个角度简化此定义-真是太糟糕了!
是否有任何内置方法可以让我摆脱嵌套的错误检查内容?我可以用比这更简单的方法返回NonRectError
吗?