Rust 如何对浮点向量进行二进制搜索?
如果您有一个Rust 如何对浮点向量进行二进制搜索?,rust,Rust,如果您有一个Vec,您将使用该方法 出于我不理解的原因,f32和f64没有实现Ord。由于基元类型来自标准库,因此您不能自己在基元类型上实现Ord,因此您似乎无法使用此方法 如何有效地做到这一点 我真的必须在包装器结构中包装f64,并在其上实现Ord?必须这样做似乎非常痛苦,需要大量的transmute来无理由地不安全地来回转换数据块 出于我不理解的原因,f32和f64没有实现Ord 因为!简短的版本是浮点数有一个特殊的值NaN,而不是一个数字。IEEE浮点数规范规定1NaN和NaN==NaN均
Vec
,您将使用该方法
出于我不理解的原因,f32
和f64
没有实现Ord
。由于基元类型来自标准库,因此您不能自己在基元类型上实现Ord
,因此您似乎无法使用此方法
如何有效地做到这一点
我真的必须在包装器结构中包装f64
,并在其上实现Ord
?必须这样做似乎非常痛苦,需要大量的transmute
来无理由地不安全地来回转换数据块
出于我不理解的原因,f32和f64没有实现Ord
因为!简短的版本是浮点数有一个特殊的值NaN,而不是一个数字。IEEE浮点数规范规定1
、1>NaN
和NaN==NaN
均为false
说:
构成一个整体的类型的特征
这意味着比较需要具有总体性:
a≤ b或b≤ a
但是我们刚刚看到浮点没有这个属性
因此,是的,您将需要创建一个包装器类型,以某种方式处理比较。也许在你的情况下,你可以断言浮点值永远不是NaN,然后调用常规特征。下面是一个例子:
use std::cmp::Ordering;
#[derive(PartialEq,PartialOrd)]
struct NonNan(f64);
impl NonNan {
fn new(val: f64) -> Option<NonNan> {
if val.is_nan() {
None
} else {
Some(NonNan(val))
}
}
}
impl Eq for NonNan {}
impl Ord for NonNan {
fn cmp(&self, other: &NonNan) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
fn main() {
let mut v: Vec<_> = [2.0, 1.0, 3.0].iter().map(|v| NonNan::new(*v).unwrap()).collect();
v.sort();
let r = v.binary_search(&NonNan::new(2.0).unwrap());
println!("{:?}", r);
}
使用std::cmp::排序;
#[推导(PartialEq,PartialOrd)]
结构NonNan(f64);
impl NonNan{
fn新(val:f64)->选项{
如果val.is_nan(){
没有一个
}否则{
一些(非南(瓦尔))
}
}
}
非NaN{}的impl Eq
为NonNan请求{
fn cmp(&self,其他:&NonNan)->订购{
self.partial_cmp(其他).unwrap()
}
}
fn main(){
让mut v:Vec=[2.0,1.0,3.0].iter().map(|v | NonNan::new(*v).unwrap()).collect();
v、 排序();
让r=v.binary_搜索(&NonNan::new(2.0).unwrap());
println!(“{:?}”,r);
}
切片方法之一是,您可以使用f32
/f64
执行PartialOrd
,因此,如果您知道它们可以永不成为NaN
,您可以打开部分cmp
的结果:
fn main() {
let values = [1.0, 2.0, 3.0, 4.0, 5.0];
let location = values.binary_search_by(|v| {
v.partial_cmp(&3.14).expect("Couldn't compare values")
});
match location {
Ok(i) => println!("Found at {}", i),
Err(i) => println!("Not found, could be inserted at {}", i),
}
}
实现可用于此操作的ord\u subset\u binary\u search()
方法
从他们的自述:
let mut s = [5.0, std::f64::NAN, 3.0, 2.0];
s.ord_subset_sort();
assert_eq!(&s[0..3], &[2.0, 3.0, 5.0]);
assert_eq!(s.ord_subset_binary_search(&5.0), Ok(2));
assert_eq!(s.iter().ord_subset_max(), Some(&5.0));
assert_eq!(s.iter().ord_subset_min(), Some(&2.0));
如果您确信您的浮点值永远不会是NaN,那么您可以使用中的包装器来表达这种语义。具体来说,该类型实现了
Ord
,并且每当程序尝试执行无效操作时,该类型就会崩溃:
use decorum::Ordered;
fn foo() {
let ordered = Ordered<f32>::from_inner(10.);
let normal = ordered.into()
}
使用礼仪::有序;
fn foo(){
let ordered=ordered::from_inner(10.);
让normal=ordered.into()
}
切片扩展方法之一是二进制搜索方法,您可以使用它f32
/f64
实现PartialOrd
,因此如果您知道它们永远不会是NaN
,您可以打开partial\u cmp
的结果:可以使用或板条箱。看见