如何将向量与自身的反向版本进行比较?
How do I compare a vector against a reversed version of itself?
为什么不能编译?
fn isPalindrome<T>(v: Vec<T>) -> bool {
return v.reverse() == v;
}
我明白了
error[E0308]: mismatched types
--> src/main.rs:2:25
|
2 | return v.reverse() == v;
| ^ expected (), found struct `std::vec::Vec`
|
= note: expected type `()`
found type `std::vec::Vec<T>`
在 the documentation 上阅读您正在使用的函数:
Reverse the order of elements in a slice, in place.
或者检查函数签名:
fn reverse(&mut self)
方法的return值为单位类型,空元组()
。您无法将其与向量进行比较。
在风格上,Rust 使用 4 space 缩进,snake_case
函数和变量标识符,并且在块的末尾有一个隐式的 return。您应该适应新语言中的这些约定。
此外,如果您不向矢量添加项目,您应该 。
为了解决您的问题,我们将使用迭代器来比较切片。您可以获得切片的前向和后向迭代器,与反转整个数组相比,这需要非常少量的 space 。 Iterator::eq
让你比较简洁。
您还需要声明 T
可与自身进行比较,这需要 Eq
or PartialEq
。
fn is_palindrome<T>(v: &[T]) -> bool
where
T: Eq,
{
v.iter().eq(v.iter().rev())
}
fn main() {
println!("{}", is_palindrome(&[1, 2, 3]));
println!("{}", is_palindrome(&[1, 2, 1]));
}
如果你想做效率较低的space版本,你必须自己分配一个新向量:
fn is_palindrome<T>(v: &[T]) -> bool
where
T: Eq + Clone,
{
let mut reverse = v.to_vec();
reverse.reverse();
reverse == v
}
fn main() {
println!("{}", is_palindrome(&[1, 2, 3]));
println!("{}", is_palindrome(&[1, 2, 1]));
}
请注意,我们现在还需要 Clone
向量中的项目,因此我们将 trait bound 添加到方法中。
因为你只需要看前半部分和后半部分,你可以使用DoubleEndedIterator
trait(方法.next()
和.next_back()
)来查看成对的前半部分和后半部分以这种方式返回元素:
/// Determine if an iterable equals itself reversed
fn is_palindrome<I>(iterable: I) -> bool
where
I: IntoIterator,
I::Item: PartialEq,
I::IntoIter: DoubleEndedIterator,
{
let mut iter = iterable.into_iter();
while let (Some(front), Some(back)) = (iter.next(), iter.next_back()) {
if front != back {
return false;
}
}
true
}
这个版本更通用一些,因为它支持任何双端迭代器,例如 slice 和 chars 迭代器。
它只检查每个元素一次,如果迭代器的长度是奇数,它会自动跳过剩余的中间元素。
为什么不能编译?
fn isPalindrome<T>(v: Vec<T>) -> bool {
return v.reverse() == v;
}
我明白了
error[E0308]: mismatched types
--> src/main.rs:2:25
|
2 | return v.reverse() == v;
| ^ expected (), found struct `std::vec::Vec`
|
= note: expected type `()`
found type `std::vec::Vec<T>`
在 the documentation 上阅读您正在使用的函数:
Reverse the order of elements in a slice, in place.
或者检查函数签名:
fn reverse(&mut self)
方法的return值为单位类型,空元组()
。您无法将其与向量进行比较。
在风格上,Rust 使用 4 space 缩进,snake_case
函数和变量标识符,并且在块的末尾有一个隐式的 return。您应该适应新语言中的这些约定。
此外,如果您不向矢量添加项目,您应该
为了解决您的问题,我们将使用迭代器来比较切片。您可以获得切片的前向和后向迭代器,与反转整个数组相比,这需要非常少量的 space 。 Iterator::eq
让你比较简洁。
您还需要声明 T
可与自身进行比较,这需要 Eq
or PartialEq
。
fn is_palindrome<T>(v: &[T]) -> bool
where
T: Eq,
{
v.iter().eq(v.iter().rev())
}
fn main() {
println!("{}", is_palindrome(&[1, 2, 3]));
println!("{}", is_palindrome(&[1, 2, 1]));
}
如果你想做效率较低的space版本,你必须自己分配一个新向量:
fn is_palindrome<T>(v: &[T]) -> bool
where
T: Eq + Clone,
{
let mut reverse = v.to_vec();
reverse.reverse();
reverse == v
}
fn main() {
println!("{}", is_palindrome(&[1, 2, 3]));
println!("{}", is_palindrome(&[1, 2, 1]));
}
请注意,我们现在还需要 Clone
向量中的项目,因此我们将 trait bound 添加到方法中。
因为你只需要看前半部分和后半部分,你可以使用DoubleEndedIterator
trait(方法.next()
和.next_back()
)来查看成对的前半部分和后半部分以这种方式返回元素:
/// Determine if an iterable equals itself reversed
fn is_palindrome<I>(iterable: I) -> bool
where
I: IntoIterator,
I::Item: PartialEq,
I::IntoIter: DoubleEndedIterator,
{
let mut iter = iterable.into_iter();
while let (Some(front), Some(back)) = (iter.next(), iter.next_back()) {
if front != back {
return false;
}
}
true
}
这个版本更通用一些,因为它支持任何双端迭代器,例如 slice 和 chars 迭代器。
它只检查每个元素一次,如果迭代器的长度是奇数,它会自动跳过剩余的中间元素。