Programmieren in Rust

Beispiele: Wortliste

Vorgelegt werden soll ein Programm das folgendes tut:

Musterlösung 1

use std::collections::HashMap;

fn string_to_words(s: &str) -> Vec<String> {
    let mut acc: Vec<String> = Vec::new();
    let mut buffer = String::new();
    for c in s.chars() {
        if c.is_alphabetic() {
            buffer.push(c);
        } else {
            if !buffer.is_empty() {
                acc.push(buffer.clone());
                buffer.clear();
            }
        }
    }
    acc
}

fn unique(v: &[String]) -> Vec<String> {
    let mut m: HashMap<String, ()> = HashMap::new();
    for s in v {
        m.insert(s.clone(), ());
    }
    let mut acc: Vec<String> = Vec::new();
    for (key, _) in m {
        acc.push(key);
    }
    acc
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let path = &args[1];
    let s = match std::fs::read_to_string(path) {
        Ok(s) => s,
        _ => {
            println!("Could not read file {}.", path);
            return;
        }
    };
    let mut words = string_to_words(&s);
    words = unique(&words);
    words.sort();
    println!("{:?}", words);
}

Musterlösung 2 (fortgeschritten)

use std::collections::HashSet;
use std::iter::FromIterator;
use std::hash::Hash;

fn string_to_words(s: &str) -> impl Iterator<Item = &str> + '_ {
    s.split(|x: char| !x.is_alphabetic()).filter(|&x| x != "")
}

fn unique<T: Eq + Hash>(i: impl IntoIterator<Item = T>) -> Vec<T> {
    HashSet::<T>::from_iter(i.into_iter()).into_iter().collect()
}

fn main() {
    let argv: Vec<String> = std::env::args().collect();
    let path = &argv[1];
    let s = match std::fs::read_to_string(path) {
        Ok(s) => s,
        _ => {
            println!("Could not read file {}.", path);
            return;
        }
    };
    let mut words = unique(string_to_words(&s));
    words.sort();
    println!("{:?}", words);
}