如何习惯地将列表中的每个项目与其他项目进行比较



我有一个点向量。我想计算每个点之间的距离。要做到这一点,我传统上会使用一对嵌套的循环,其中内部循环在外部循环前面保留一个元素。通过这种方式,我只比较每对点一次。

for i in 0..len {
for j in i + 1..len {
// calculate distance between points i and j
}
}

我想知道是否有更惯用的方法来实现这种类型的"三角形"嵌套循环。

下面是一个更完整的列表,显示了distances矩阵的计算和存储,该矩阵允许我访问任何距离对。

Rust Payground Link

use rand::Rng;
#[derive(Debug)]
pub struct Point {
x: i32,
y: i32,
}
impl Point {
pub fn rnd(width: i32, height: i32) -> Point {
let mut rng = rand::thread_rng();
Point {
x: rng.gen_range(0..width),
y: rng.gen_range(0..height),
}
}
}
pub fn get_distances(points: &[Point]) -> Vec<Vec<i32>> {
let len = points.len();
let mut distances: Vec<Vec<i32>> = vec![vec![0; len]; len];
for i in 0..len {
for j in i + 1..len {
let mut distance =
(points[i].x - points[j].x).pow(2) + 
(points[i].y - points[j].y).pow(2);
distance = (distance as f32).sqrt() as i32;
distances[i][j] = distance;
distances[j][i] = distance;
}
}
distances
}
fn main() {
let points: Vec<Point> = (0..5).map(|_| Point::rnd(400, 600)).collect();
let distances = get_distances(&points);
println!("{:#?}", distances);
}

您可以利用迭代器,尽管嵌套的for循环足够清晰:

pub fn get_distances_iter(points: &[Point]) -> Vec<Vec<i32>> {
let len = points.len();
let mut distances: Vec<Vec<i32>> = vec![vec![0; len]; len];
for (i, j) in (0..len)
.map(|i| (i + 1..len).map(move |j| (i, j)))
.flatten()
{
let mut distance = (points[i].x - points[j].x).pow(2) + (points[i].y - points[j].y).pow(2);
distance = (distance as f32).sqrt() as i32;
distances[i][j] = distance;
distances[j][i] = distance;
}
distances
}

游乐场

相关内容