Решение на Search от Радослав Георгиев
Към профила на Радослав Георгиев
Резултати
- 12 точки от тестове
- 1 бонус точка
- 13 точки общо
- 4 успешни тест(а)
- 1 неуспешни тест(а)
Код
use std::str::CharIndices;
// Опционално
struct WordIterator<'a> {
word: &'a str,
iterator: CharIndices<'a>,
}
// Опционално
impl<'a> WordIterator<'a> {
pub fn new(text: &'a str) -> Self {
Self {
word: text,
iterator: text.char_indices(),
}
}
}
// Опционално
impl<'a> Iterator for WordIterator<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
let iter = self.iterator.by_ref().skip_while(|&(_, ch)| !ch.is_alphabetic());
let mut iter_word = iter.take_while(|&(_, ch)| ch.is_alphabetic());
if let (Some((first, _)), Some((last, _))) = (iter_word.next(), iter_word.last()) {
Some(&self.word[first .. (last + 1)])
} else {
None
}
}
}
pub fn extract_words(text: &str) -> Vec<String> {
WordIterator::new(text).map(String::from).collect()
}
use std::collections::HashSet;
pub struct TextIndex {
index: HashSet<String>,
}
impl TextIndex {
pub fn new() -> Self {
Self {
index: HashSet::new(),
}
}
pub fn push(&mut self, text: &str) {
self.index.insert(text.to_string());
}
pub fn search(&self, query: &str) -> HashSet<&str> {
let words = extract_words(query);
self.index
.iter()
.filter(|text| {
extract_words(text).iter().any(|word| words.contains(word))
})
.map(|text| text.as_ref())
.collect()
}
}
Лог от изпълнението
Compiling solution v0.1.0 (file:///tmp/d20180105-6053-7tmsaq/solution) Finished dev [unoptimized + debuginfo] target(s) in 4.83 secs Running target/debug/deps/solution-3f98bfa5c86a5dd9 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Running target/debug/deps/solution_test-3d9e4ea2eafbbc82 running 5 tests test solution_test::test_extract_words_basic ... ok test solution_test::test_extract_words_extra ... FAILED test solution_test::test_search_multiple_words ... ok test solution_test::test_search_special_cases ... ok test solution_test::test_search_word ... ok failures: ---- solution_test::test_extract_words_extra stdout ---- thread 'solution_test::test_extract_words_extra' panicked at 'byte index 5 is not a char boundary; it is inside 'о' (bytes 4..6) of `Кво стаа, Пешо?`', /checkout/src/libcore/str/mod.rs:2243:4 note: Run with `RUST_BACKTRACE=1` for a backtrace. failures: solution_test::test_extract_words_extra test result: FAILED. 4 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--test solution_test'
История (2 версии и 1 коментар)
Радослав качи решение на 05.01.2018 16:55 (преди над 7 години)
+use std::str::CharIndices;
+
+// Опционално
+struct WordIterator<'a> {
+ word: &'a str,
+ iterator: CharIndices<'a>,
+}
+
+// Опционално
+impl<'a> WordIterator<'a> {
+ pub fn new(text: &'a str) -> Self {
+ Self {
+ word: text,
+ iterator: text.char_indices(),
+ }
+ }
+}
+
+// Опционално
+impl<'a> Iterator for WordIterator<'a> {
+ type Item = &'a str;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let iter = self.iterator.by_ref().skip_while(|&(_, ch)| !ch.is_alphabetic());
+ let mut iter_word = iter.take_while(|&(_, ch)| ch.is_alphabetic());
+ if let (Some((first, _)), Some((last, _))) = (iter_word.next(), iter_word.last()) {
+ Some(&self.word[first .. (last + 1)])
+ } else {
+ None
+ }
+ }
+}
+
pub fn extract_words(text: &str) -> Vec<String> {
- text.split(|ch: char| !ch.is_alphabetic())
- .filter(|word| !word.is_empty())
- .map(|word| word.to_string())
- .collect()
+ WordIterator::new(text).map(String::from).collect()
}
use std::collections::HashSet;
pub struct TextIndex {
index: HashSet<String>,
}
impl TextIndex {
pub fn new() -> Self {
Self {
index: HashSet::new(),
}
}
pub fn push(&mut self, text: &str) {
self.index.insert(text.to_string());
}
pub fn search(&self, query: &str) -> HashSet<&str> {
let words = extract_words(query);
self.index
.iter()
.filter(|text| {
extract_words(text).iter().any(|word| words.contains(word))
})
.map(|text| text.as_ref())
.collect()
}
}
Бонус точка за word iterator-а. Само дето с кирилицата малко не ти се е получило :). Подозирам, че вместо да събереш с едно, си можел да събереш с char::len_utf8.