rust - 检测按顺序发生的字符串切片的重复元素

标签 rust iterator higher-order-functions method-chaining

我需要检测并列出切片中重复次数大于或等于 N 次的字符串字符。我已经成功地用 Rust 编写了非高阶函数解决方案(如下),但我想知道这是否可以简化为链接 iter 方法。

想法:

let v = "1122253225";
let n = 2;

输出:

There are 2 repetition of '1'
There are 3 repetition of '2'
There are 2 repetition of '2'

发生重复的索引并不重要。重复必须按顺序发生(即,3 次重复的“2”与其他 2 次重复的“2”被其他值分隔开,算作单独的输出行)。

我的非迭代器解决方案:

    let mut cur_ch = '\0';
    let mut repeat = 0;

    for ch in v.chars() {
        if ch == cur_ch {
            repeat = repeat + 1;
        }
        else {
            if repeat >= n {
                printf!("There are {} repetition of '{}'", repeat, cur_ch);
            }
            cur_ch = ch;
            repeat = 1;
        }
    }

    if repeat >= n {
        printf!("There are {} repetition of '{}'", repeat, cur_ch);
    }

它可以工作,但是有没有更好的方法通过链接 iter 方法来做到这一点?

最佳答案

这是一个使用 scan 的解决方案和filter_map :

fn main() {
    let s = "112225322555";
    let n = 2;

    let i = s
        .chars()
        .map(|v| Some(v))
        .chain(std::iter::once(None))
        .scan((0, None), |(count, ch), v| match ch {
            Some(c) if *c == v => {
                *count += 1;
                Some((None, *count))
            }
            _ => Some((ch.replace(v), std::mem::replace(count, 1))),
        })
        .filter_map(|(ch, count)| match ch {
            Some(Some(ch)) if count >= n => Some((ch, count)),
            _ => None,
        });

    for (ch, num) in i {
        println!("There are {} repititions of {}", num, ch);
    }
}

Playground Link

第一步是使用scan计算相邻字符的数量。 scan 的第一个参数是一个状态变量,它会传递给作为第二个参数传递的闭包的每次调用。在本例中,状态变量是一个包含当前字符及其出现次数的元组。

注意:

  • 我们需要将迭代扩展到我们正在分析的字符串末尾之外(否则我们会错过字符串末尾包含一系列符合条件的字符的情况)。我们通过将迭代映射到 Option<char> 来做到这一点然后链接到单个 None 。这比特殊大小写字符(例如 \0)要好。 ,这样我们就可以数 \0字符。

  • 出于同样的原因,我们使用 Option<char>作为状态元组中的当前字符。

  • scan的返回值是 (Option<Option<char>>, i32) 上的迭代器。元组中的第一个值将是 None对于迭代器中的每个重复字符,而在字符更改的每个边界处,它将是 Some(Some(char))

  • 我们使用replace返回当前字符和计数,同时将状态元组设置为新值

最后一步是使用filter_map至:

  • 删除 (None, i32)变体,表示传入字符没有变化

  • 过滤掉计数未达到限制的情况n .

关于rust - 检测按顺序发生的字符串切片的重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63327968/

相关文章:

javascript - 如何用包含 TypeScript 中较新对象的数组替换对象数组?

javascript - 您可以使用 python 中的映射或其他高阶函数来跟踪索引吗?

visual-studio-code - 使用 VS Code 时如何解决 Rust 中的 "unresolved import"?

function - 定义将参数传递给函数的宏

java - FindBugs 警告 : Inefficient use of keySet iterator

C++ 何时以及如何使用 std::iterator value_type、引用、指针?

rust - 找出介于0和带符号int的无符号int之和之间的最大值

azure - 使用 Azure Monitor 数据收集器 API 时授权 header 中的签名无效

c++ - std::upper_bound 中的 boost::transform_iterator 编译错误

recursion - 递归函数是高阶函数的特例吗