string - 如何使用迭代器确定两个字符串在函数式风格中是否只有一个不同的字符?

标签 string rust char iterable

我需要编写一个函数,以顺序方式检查两个 String 是否只有一个字符不同,即只有 diff("aba", "abc") == true , diff("aab", "cab") == false,字符串长度相等)。

我用命令式风格编写了代码,但是看起来很难看,我想用迭代器以函数式风格编写它。

我想它应该是带有 s1.chars()..enumerate() + 一些闭包的东西,它可以检测两个字符串中的一个不同字符。

fn has_one_difference(s1: &String, s2: &String) -> bool {
    let mut diff_chars_limit = false;
    let mut s1_chars = s1.chars();
    let mut s2_chars = s2.chars();

    for index in 0..s1.len() {
        if s1_chars.nth(index).unwrap() != s2_chars.nth(index).unwrap() {
            if diff_chars_limit {
                return false
            } else {
                diff_chars_limit = true
            }
        }
    }

    return diff_chars_limit;
}

我收到此错误:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:345:21

在字符串迭代的最后一个字符上。

最佳答案

首先,我将您的命令式代码更正为

  • 删除对字符迭代器的极其低效的基于索引的访问,
  • 如果 s1 更长但等于 s2,则消除崩溃,并将其替换为代码以其他方式展示的相同“忽略较长字符串的尾部”行为周围,​​
  • 使用 str 而不是 String,因为几乎没有充分的理由将 &String 传递给函数,并且
  • 修复一些小的样式问题;特别是在返回值中添加分号,但使用尾部返回表达式而不返回。这是更惯用的 Rust。

看起来像这样:

fn has_one_difference(s1: &str, s2: &str) -> bool {
    let mut found_one_difference = false;

    for (c1, c2) in s1.chars().zip(s2.chars()) {
        if c1 != c2 {
            if found_one_difference {
                return false;
            } else {
                found_one_difference = true
            }
        }
    }

    found_one_difference
}

现在对于函数版本,我只需编写一个迭代器,看看是否可以对其调用 next() 两次:

fn has_one_difference_functional(s1: &str, s2: &str) -> bool {
    // An iterator over different char pairs.
    let mut iter = s1.chars().zip(s2.chars())
        .filter(|(c1, c2)| c1 != c2);

    // First call to next() must succeed (one difference), second must fail.   
    iter.next().is_some() && iter.next().is_none()
}

这并不完全实用,但我认为它总体上是简洁性和可读性的最佳组合。一个简单的全功能版本将在组合迭代器上调用 count() 并将其与 1 进行比较,但这不是短路,因此效率低于需要的水平。可以使用 try_fold 编写更高效的版本,但由于复杂性而失去了可读性,因此我只考虑将其用于 has_n_differences 函数。

关于string - 如何使用迭代器确定两个字符串在函数式风格中是否只有一个不同的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55448803/

相关文章:

c - c中的字符串自动连接

python - 如何按相反顺序找到两个字母之间的长度/间隔?

rust - 返回对具有泛型 Fn 特征/值的泛型类型的引用

c++ - 从 boost::array<char, 100> 中提取字符集

c - 匹配字符串最后一个字符的函数

c++ - 空终止符在比较时给字符串长度带来麻烦

c - 复合字符数组和字符串文字之间是否存在任何内部差异?

rust - 如何在Rust SPECS中读取组件并写入具有相同组件的新实体?

rust - 预期错误的原因(),在Rust中找到struct `std::vec::Vec`?

java - 如何清除单个字符串的不同部分,同时使结果成为字符串本身?