Решение на Spell Checker от Людмил Данаилов

Обратно към всички решения

Към профила на Людмил Данаилов

Резултати

  • 0 точки от тестове
  • 0 бонус точки
  • 0 точки общо
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)

Код

use std::fmt;
use std::collections::HashSet;
pub const ALPHABET_EN: &'static str = "abcdefghijklmnopqrstuvwxyz";
pub const ALPHABET_BG: &'static str = "абвгдежзийклмнопрстуфхцчшщъьюя";
pub fn clean_line(input: &str) -> String {
let chars: String = input.chars().filter(|&n| n.is_alphabetic() || n == '-' || n == '\'' || n.is_whitespace()).collect::<String>().trim().to_string();
return chars;
}
pub struct WordCounter {
word_counter: Vec<(String, u32)>
}
impl WordCounter {
pub fn new() -> Self {
let vec: Vec<(String, u32)> = Vec::new();
return WordCounter{word_counter: vec};
}
pub fn from_str(input: &str) -> Self {
let mut vec: Vec<(String, u32)> = Vec::new();
for x in input.lines() {
let a = clean_line(x);
if a == "" {
return WordCounter{word_counter: vec![]};
}
vec = a.split(' ').collect::<Vec<&str>>().iter().map(|n| (n.to_string(), 1)).collect::<Vec<(String, u32)>>();
}
return WordCounter{word_counter: vec};
}
pub fn words(&self) -> Vec<&String> {
let vec: Vec<&String> = self.word_counter.iter().map(|n| &(n.0)).collect::<Vec<&String>>();
return vec;
}
pub fn add(&mut self, item: &str) {
let string: String = clean_line(item).to_lowercase();
while let Some(mut i) = self.word_counter.clone().into_iter().next() {
if string == item {
i.1 += 1;
return;
}
}
self.word_counter.push((string, 1));
}
pub fn get(&self, word: &str) -> u32 {
while let Some(i) = self.word_counter.clone().into_iter().next() {
if i.0 == word.to_string() {
return i.1;
}
}
return 0;
}
pub fn total_count(&self) -> u32 {
let sum: u32 = self.word_counter.iter().map(|n| n.1 as u32).sum();
return sum;
}
}
impl fmt::Display for WordCounter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "WordCounter, total count: {:?}\n", self.total_count())?;
self.word_counter.iter().map(|n| write!(f, "{}: {}", n.0, n.1)).collect()
}
}
pub struct SpellChecker {
alphabet: String,
word_counter: WordCounter
}
impl SpellChecker {
pub fn new(corpus: &str, alphabet: &str) -> Self {
let word_counter = WordCounter::from_str(corpus);
return SpellChecker{alphabet: alphabet.to_string(), word_counter: word_counter}
}
pub fn correction(&self, word: &str) -> String {
unimplemented!();
}
pub fn probability(&self, word: &str) -> f64 {
return (self.word_counter.get(word) / self.word_counter.total_count()) as f64;
}
pub fn known(&self, words: &HashSet<String>) -> Vec<String> {
let mut vector: Vec<String> = Vec::new();
for x in words {
if self.word_counter.get(&x) != 0 {
vector.push(x.to_string());
}
}
return vector;
}
pub fn candidates<'a>(&self, word: &str) -> Vec<String> {
let a = HashSet::new();
if self.known(&a).len() != 0 {
return self.known(&a);
}
if self.known(&self.edits1(word)).len() != 0 {
return self.known(&self.edits1(word));
}
if self.known(&self.edits2(word)).len() != 0 {
return self.known(&self.edits2(word));
}
return self.known(&a);
}
/// Всички думи, които са на една промяна разстояние от дадената дума:
///
/// - Една буква изтрита на коя да е позиция
/// - Две букви разменени (една до друга)
/// - Една буква от азбуката замества коя да е буква от думата
/// - Една буква от азбуката добавена в думата на която и да е позиция
///
/// Изхода е HashSet, понеже две различни промени е възможно да продуцират един и същ резултат,
/// а дубликати не ни интересуват.
///
pub fn edits1(&self, word: &str) -> HashSet<String> {
unimplemented!()
}
/// Всички думи, които са на две промени разстояние от дадената дума. Вижте инструкциите на
/// edits1 за това какво е "промяна" и направете тези промени по променените веднъж думи.
///
pub fn edits2(&self, word: &str) -> HashSet<String> {
unimplemented!()
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20200114-2173579-1suh1c9/solution)
warning: unused variable: `word`
  --> src/lib.rs:90:30
   |
90 |     pub fn correction(&self, word: &str) -> String {
   |                              ^^^^ help: consider prefixing with an underscore: `_word`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `word`
   --> src/lib.rs:133:26
    |
133 |     pub fn edits1(&self, word: &str) -> HashSet<String> {
    |                          ^^^^ help: consider prefixing with an underscore: `_word`

warning: unused variable: `word`
   --> src/lib.rs:140:26
    |
140 |     pub fn edits2(&self, word: &str) -> HashSet<String> {
    |                          ^^^^ help: consider prefixing with an underscore: `_word`

warning: field is never used: `alphabet`
  --> src/lib.rs:80:5
   |
80 |     alphabet: String,
   |     ^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(dead_code)]` on by default

warning: unused variable: `word`
  --> src/lib.rs:90:30
   |
90 |     pub fn correction(&self, word: &str) -> String {
   |                              ^^^^ help: consider prefixing with an underscore: `_word`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `word`
   --> src/lib.rs:133:26
    |
133 |     pub fn edits1(&self, word: &str) -> HashSet<String> {
    |                          ^^^^ help: consider prefixing with an underscore: `_word`

warning: unused variable: `word`
   --> src/lib.rs:140:26
    |
140 |     pub fn edits2(&self, word: &str) -> HashSet<String> {
    |                          ^^^^ help: consider prefixing with an underscore: `_word`

warning: field is never used: `alphabet`
  --> src/lib.rs:80:5
   |
80 |     alphabet: String,
   |     ^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(dead_code)]` on by default

error[E0277]: can't compare `std::string::String` with `&std::string::String`
   --> tests/solution_test.rs:169:5
    |
169 |     assert_eq!(known_words, vec![&String::from("four"), &String::from("one")]);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::string::String == &std::string::String`
    |
    = help: the trait `std::cmp::PartialEq<&std::string::String>` is not implemented for `std::string::String`
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<std::vec::Vec<&std::string::String>>` for `std::vec::Vec<std::string::String>`
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `solution`.

To learn more, run the command again with --verbose.

История (1 версия и 1 коментар)

Людмил качи първо решение на 14.01.2020 16:36 (преди над 5 години)

Това не е правилната сигнатура за този метод:

pub fn known(&self, words: &HashSet<String>) -> Vec<String> {

Разбирам защо си го направил, не си успял да измислиш как да имплементираш решението иначе. Но 1) lifetimes са важни и няма как да направим домашно, което да не изисква да ги упражни (а това наистина не беше трудно, разгледай останалите решения) и 2) когато функцията ти има различна сигнатура, кода не се компилира, и тестовете няма изобщо как да тръгнат, така че получаваш 0 точки. Сори, но сме дали условие с конкретна сигнатура на функциите.