Rust之美迭代器在算法中的应用

前言

在本文中我们将从一个简单的算法题引出Rust语言中迭代器相关的几个方法,帮助大家理解chars,all ,try_fold,enumerate,try_for_each,char_indices的用法。 ​

题目如下

我们定义,在以下情况时,单词的大写用法是正确的:

全部字母都是大写,比如 “USA” 。 单词中所有字母都不是大写,比如 “leetcode” 。 如果单词不只含有一个字母,只有首字母大写,
比如 “Google” 。 给你一个字符串 word 。如果大写用法正确,返回 true ;否则,返回 false 。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/detect-capital
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

根据题意,满足条件的字符串就是

  • 要么字符串中的字符都是小写;
  • 要么都是大写;
  • 要么第一个是大写,剩下的是小写。

原始的解法

根据上面的分析,我们只需要做下面三个判断就可以了

  • word中字符如果都是大写,返回true
  • word中字符是否都是小写,返回true
  • word中首字符大写且剩余字符小写,返回true
  • 其它情况返回false
pub fn detect_capital_use(word: String) -> bool {
   
    if word.len() < 2 {
   
        return true;
    }

    // 判断都是大写
    let mut res = true;
    for c in word.as_bytes() {
   
        if c.is_ascii_lowercase() {
   
            res = false;
            break;
        }
    }
    if res {
   
        return res;
    }

    // 判断都是小写
    let mut res = true;
    for c in word.as_bytes() {
   
        if c.is_ascii_uppercase() {
   
            res = false;
            break;
        }
    }
    if res {
   
        return res;
    }

    // 判断首字母大写,剩余小写
    if word.as_bytes()[0].is_ascii_lowercase() {
   
        return false;
    }
    let mut res = true;
    for c in &word.as_bytes()[1..] {
   
        if c.is_ascii_uppercase() {
   
            res = false;
            break;
        }
    }
    if res {
   
        return res;
    }

    false
}

使用迭代器

上面的代码中使用了三次遍历,如果使用Rust中的迭代器,可以非常简洁,对应代码如下:

pub fn detect_capital_use(word: String) -> bool {
   

    if word.len() ==0{
   
        return true
    }
    if word.len() ==1{
   
        return true
    }

    let mut word1 = word.chars(); // 返回word中字符的迭代器
    if word1.all(|x|x.is_lowercase()){
    // 都是小写
        return true 
    }

    let mut word1 = word.chars();
    if word1.all(|x|x.is_uppercase()){
    // 都是大写
        return true 
    }

    let mut word1 = word.chars();
    let first_word = word1.next().unwrap();// 获取第一个字符
    if first_word.is_lowercase(){
     //首字符大写
        return false
    }
    if word1.all(|x|x.is_lowercase()){
    // 剩下的小写
        return true 
    }

    false

}

代码分析

上面代码中我们使用.chars()方法得到String的字符迭代器,然后利用了rust中迭代器的all 方法完成了该功能,整个代码逻辑非常贴合人类的自然语言,可读性非常强。下面我们先介绍下 all 方法: 迭代器的all 方法用来判断迭代器所遍历的所有项是否满足闭包的条件

  1. Tests if every element of the iterator matches a predicate.
  2. all() takes a closure that returns true or false. It applies this closure to each element of the iterator, and if they all return true, then so does all(). If any of them return false, it returns false.
  3. all() is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.
  4. An empty iterator returns true.

翻译过来就是

  1. 判断迭代器中的每一个元素是否满足断言(也就是传入的闭包函数)。
  2. all() 接受一个闭包作为参数,这个闭包返回true或false。all() 在迭代器遍历过程中,把每一个元素传入闭包,如果所有的元素传入闭包中都返回true,那么all() 就返回true,否则all() 返回false。
  3. all() 是短路;换句话说,在遍历的过程中,一旦某个元素传入闭包后返回false,就会立刻停止遍历,无论后面元素的结果是什么,最终all() 的结果是 false
  4. 一个空的迭代器的all() 永远返回 true

all() 对应的源码如下:

#[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    fn all
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值