繁体   English   中英

如何编写Rust函数以查找两个字符串之间的不同字符?

[英]How can I write a Rust function to find different characters between two strings?

字符的顺序并不重要,但数量很重要。 我的意思是aaabaaa等于6a + b ,该函数就像数学减法。 例如:

fn diff(a: String, b: String) -> String {}
diff("aabbac", "accba") => "ab"
---------------------------------
"aabbac" = (3a+2b+c)
"accba" = (2a+b+2c)
(3a+2b+c) - (2a+b+2c) = a+b // -c is ignored

通常的技术是创建一个函数来计算每个字符的出现次数,例如Python中的collections.Counter ,然后将这些数字与字符串ab进行比较。

Rust标准库文档包含一个可完成此工作的代码段 这是一种接受任何迭代器的改编:

use std::collections::HashMap;
use std::hash::Hash;
use std::iter::Iterator;

fn counter<T, I>(it: I) -> HashMap<T, usize>
where
    T: Eq + Hash,
    I: Iterator<Item = T>,
{
    let mut count_by_element = HashMap::new();
    for e in it {
        *count_by_element.entry(e).or_insert(0) += 1;
    }
    count_by_element
}

现在我们知道了如何构建映射char -> count ,我们只需要比较字符串ab的计数:

use std::iter;

fn diff(a: &str, b: &str) -> String {
    let mut v: Vec<char> = vec![];
    let counter_a = counter(a.chars());
    let counter_b = counter(b.chars());
    for (c, n_a) in &counter_a {
        let n_b = counter_b.get(c).unwrap_or(&0); // how many `c` in `b`?
        if n_a > n_b {
            v.extend(iter::repeat(c).take(n_a - n_b)); // add `n_a - n_b` `c`s
        }
    }
    v.into_iter().collect::<String>() // build the String
}

如果您需要“一次性”功能,则可以忘记counter功能,而可以使用更直接的方法:

fn diff_one_shot(a: &str, b: &str) -> String {
    let mut counter = HashMap::new();
    for c in a.chars() {
        *counter.entry(c).or_insert(0) += 1; // one more
    }
    for c in b.chars() {
        *counter.entry(c).or_insert(0) -= 1; // one less
    }
    counter
        .iter()
        .filter(|(_c, &n)| n > 0) // only if more `c` in `a` than in `b`
        .flat_map(|(c, &n)| iter::repeat(c).take(n)) // `n` times `c`
        .collect::<String>()
}

例子:

fn main() {
    println!("{:?}", counter("aaabbc".chars()));
    // {'b': 2, 'c': 1, 'a': 3}
    println!("{}", diff("aaabbc", "ab"));
    //aabc
    println!("{}", diff_one_shot("aaabbc", "ab"));
    //aacb
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM