如何计算Rust中矢量的最小差异?
以下代码:
fn main() {
let vector: Vec<f64> = vec![1.025, 1.028, 1.03, 1.05, 1.051];
let mut result: Vec<f64> = Vec::new();
for i in 0..vector.len() - 1 {
result.push(vector[i] - vector[i + 1]);
}
println!("{:?}", result);
let minimum = std::cmp::min(&result[0], &result[1]);
println!("{}", minimum)
}
结果:
error[E0277]: the trait bound `f64: std::cmp::Ord` is not satisfied
--> src/main.rs:10:19
|
10 | let minimum = std::cmp::min(&result[0], &result[1]);
| ^^^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `f64`
|
= note: required because of the requirements on the impl of `std::cmp::Ord` for `&f64`
= note: required by `std::cmp::min`
挑战是:
任何时候都只能比较两个值;我该如何计算所有值?可以使用折叠还是必须是宏?
for i in 0..5 { vector[i] }
)比在向量本身for i in &vector
上创建一个迭代器更加昂贵。答案 0 :(得分:9)
使用迭代器!
在切片上,可以使用windows()
方法获取连续的元素对。在您的情况下,<div class="box">
<div class="frm">
<center><h2>Simple Form</h2></center>
<div class="line">
<label for="name">Enter Your Name</label>
<input type="text" id="name">
</div>
<div class="line">
<label for="email">Enter Your Email</label>
<input type="text" id="email">
</div>
<div class="line">
<label for="pass">Enter Your Password</label>
<input type="text" id="pass">
</div>
</div>
</div>
将产生:vector.windows(2)
,[1.025, 1.028]
,[1.028, 1.03]
,最后[1.03, 1.05]
。
这是一个迭代器,因此您可以对其应用转换。在您的情况下,我建议map
,将每对映射到对中两个元素之间的差异:[1.05, 1.051]
。并且可以使用.map(|slice| slice[0] - slice[1])
来获取绝对差异。
这仍然是一个迭代器,所以最后你可以应用min_by
,它只会产生所有元素的最小值。浮动只实现(slice[0] - slice[1]).abs()
1 ,因此:PartialOrd
。
完全放在in the playground:
.min_by(|x, y| x.partial_cmp(y).unwrap())
1 如此处所示,可以比较浮点数。然而,由于存在NaN,结果为fn main() {
let vector = vec![1.025_f64, 1.028, 1.03, 1.05, 1.051];
let minimum =
vector.windows(2)
.map(|slice| (slice[0] - slice[1]).abs())
.min_by(|x, y| x.partial_cmp(y).unwrap());
println!("{:?}", minimum);
}
。在这种情况下,假设输入数据中没有NaN,我只使用Option<Ordering>
来获取基础排序;如果一个NaN潜入,它会恐慌。
答案 1 :(得分:2)
你可以这样做:
let v = vec![1.025f64, 1.028, 1.03, 1.05, 1.051];
let min = (0..v.len() - 1)
.map(|i| (v[i] - v[i + 1]).abs())
.min_by(|a, b| a.partial_cmp(b).unwrap()); // panic on `NaN`
println!("{:?}", min);
此代码不使用临时向量来保存差异。相反,由于懒惰的迭代器,它可以动态计算所有内容。另请注意,我使用abs()
来计算绝对差异(这可能是您想要的)。
要查找最低要求,Iterator
会提供一系列方法:min()
,min_by_key
和min_by
。我用后者来处理无法比较浮动的问题。如果我们遇到NaN
值,我的代码就会引起恐慌。这可能适用于您的用例,但您可能期望NaN
值,并希望处理错误。
结果min
变量是Option<f64>
,如果向量的长度为1,则为None
。如果向量的长度为0,则在索引v[i + 1]
时会发生混乱。< / p>
关于你的“花车不准确”问题:是的,这是真的。真正解决此问题的唯一方法是使用任意精度类型。可能有几个箱子提供这种类型。但这不再是这个问题的范围了。