[炼手Rust]验证括号正确性

136 阅读2分钟

Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看一个小问题:验证括号正确性。

font-brackets-icon-linear-logo-mark-in-black-vector-52293960.jpg

提问

阿明有机会为 Bracketeer(世界五百强软件之一)编写软件。该软件是用专有语言编写的。它的大部分语法阿明都很熟悉,但有很多方括号、大括号和圆括号。尽管 Bracketeer 功能强大,但缺乏灵活性。如果源代码中有任何不平衡的方括号、大括号或圆括号,Bracketeer 就会崩溃并且必须重新启动。为了避免这种情况,阿明开始编写代码,尝试 Bracketeer 运行之前验证方括号、大括号和圆括号是否平衡。

例:
input:"{what is (42)}?"
output:true

input:"(text}"
output:false

模板:

pub fn brackets_are_balanced(string: &str) -> bool {}

分析

根据题目,我们只需要验证大括号、方括号和圆括号就行,字符上就是'{','}','[',']','(',')'。我们仔细想一下括号匹配规则,当出现')',']','}',它们的前一个也必定是'(','[','{',也就是说,当一个闭括号出现时,上一个一定是对应的开括号,不能是别的括号。根据这个思路,我们可以通过栈的方式去匹配括号,如果出现开括号('(','[','{'),就入栈,如果出现闭括号(')',']','}'),就出栈,出栈的这个括号与当前的闭括号如果匹配,那么就继续,如果不匹配,直接返回false。最后看我们的栈是否是空的,空表示我们匹配完成,证明括号匹配也就成功了。

解决方案

pub fn brackets_are_balanced(string: &str) -> bool {
    let mut brackets = vec![];
    for i in string.chars() {
        match i {
         '[' | '(' | '{' => brackets.push(i),
         ']' =>{
            if !matches!(brackets.pop(), Some('[')) {
                return false;    
            }
         },
         ')' =>{ 
            if !matches!(brackets.pop(), Some('(')) {
                return false;   
            }
         },
         '}' => { 
            if !matches!(brackets.pop(), Some('{')) {
                return false;    
            }
         },
         _ => {},
        }
    }  
    brackets.is_empty()
}

Trick

  1. Vec当做栈使用的时候,使用pushpop操作。
  2. match表达式当想匹配多个的时候,使用|进行分割。