Как новичок в Rust, я работаю над проблемами Project Euler, чтобы помочь мне почувствовать язык. Проблема 4 связана с палиндромами, и я нашел два решения для создания вектора палиндромов, но я не уверен, как они работают.
Я использую вектор строк products
, который рассчитывается следующим образом:
let mut products = Vec::new();
for i in 100..500 {
for j in 500..1000 {
products.push((i * j).to_string());
}
}
Чтобы отфильтровать эти продукты только до тех, которые являются палиндромными, у меня есть два следующих решения:
Решение 1.
let palindromes: Vec<_> = products
.iter()
.filter(|&x| x == &x.chars().rev().collect::<String>())
.collect();
Решение 2:
let palindromes: Vec<_> = products
.iter()
.filter(|&x| *x == *x.chars().rev().collect::<String>())
.collect();
Оба они дают правильный результат, но я понятия не имею, почему!
В решении 1 мы сравниваем ссылку на строку со ссылкой на только что созданную строку?
В решении 2 мы разыменуем ссылку на строку и сравниваем ее с разыменованной новой строкой?
На что я рассчитываю:
let palindromes: Vec<_> = products
.iter()
.filter(|x| x == x.chars().rev().collect::<String>())
.collect();
Я надеюсь, что кто-нибудь сможет мне объяснить:
- В чем разница между двумя моими решениями и почему они оба работают?
- Почему я не могу просто использовать
x
без ссылки или разыменования в моей функции фильтрации?
Спасибо!
String
, вы можете сравнить итераторы:.filter(|x| x.chars().eq(x.chars().rev()))
. - person Boiethios   schedule 02.05.2018collect
создает новыйString
в куче)? :) - person kazemakase   schedule 02.05.2018.eq
, это супер! Спасибо! Однако применение метода грубой силы было хорошим способом столкнуться с ловушками; спасибо @kazemakase за урок :) - person piercebot   schedule 02.05.2018