我有一个泛型,其中Num
在num
crate中定义:
//finds `x` where `f(x) == Equal` for `x ∈ [left, right)`
fn binary_search<T: Debug + Copy + PartialOrd + Num, F: FnMut(T) -> Ordering>(
mut left: T,
mut right: T, //exclusive
mut f: F,
) -> Result<T, T> {
while (left < right) {
let mid = left + (right - left) / (T::one() + T::one());
match f(mid) {
Less => left = mid + T::one(),
Greater => right = mid,
Equal => return Ok(mid),
}
}
Err(left)
}
这种二分查找对整型正确,但对浮点型(如f64
)无效。
Less => left = mid + T::one(),
T::one()
应该改为1e-6
(浮点型)和1
(整型)。这可能吗?
这是Rust Playground,其中包含一些可用的自动化测试。我希望在不破坏binary_search_01()
的情况下使binary_search_02()
通过。
3条答案
按热度按时间ctehm74n1#
Less
和Greater
臂并不对称,这就是为什么你必须调整其中一个的中点,而不是另一个。你可以通过使两个端点都包括在内来修复它,这样就不需要轻推中点了。Playground
请注意,我将最终返回值更改为
Err(right)
以使测试通过。我不确定这是否正确?如果不正确,您可以尝试使用它。mmvthczy2#
您可以定义自己的trait,并为整数和浮点类型实现它:
如果您不想为所有类型手动实现
Delta
,可以使用宏来实现:Playground
svdrlsy43#
您可以在定义了某些转换方法的位置使用
num::FromPrimitive
trait:因此,将
delta
定义为并添加它而不是
T::one()
最后的代码是这样的,它使所有的测试都通过: