Swift 栈的初试

224 阅读2分钟

栈的结构其实挺简单的,就一句话先进后出,而且push的是在最上面,pop出去的也是最后一个,按照这个思路我们来实现一下栈,同时来完成一个小小的swift算法题。

首先我们实现的栈的元素类型是不定的,所以我打算用protocol来定义一下,这样我们面对元素类型的时候就更加方便了。不多说了,上代码。

//栈
protocol Stack {    
    associatedtype Element    
    //是否为空    
    var isEmpty: Bool {get}    
    //长度    
    var size: Int {get}    
    //栈顶    var peek: Element? {get}    
    //进栈   
     mutating func push(_ newElement: Element)
       //出栈
    mutating func pop()
}

这样我们就定义好了一个栈的协议

接下来我们写一个我们需要使用的栈,因为我们下面要做的一道算法题是字符串类型的,所以我们来写一个StringStack

struct StringStack: Stack {

    typealias Element = String    
    private var stack = [Element]()    
    var isEmpty: Bool  { return stack.isEmpty }    
    var size: Int {return  stack.count}    
    var peek: Element? {return stack.last}   
     //入栈  
     mutating func push(_ newElement: Element) {      
        stack.append(newElement)
    }
    //出栈   
     mutating func pop() {        
        if stack.isEmpty {           
             return       
         }        
        stack.removeLast()    
    }
}

这样我们就完成了一个string类型的栈,如果你想要一个Int类型的, typealias Element = Int,该这个就行了,是不是很简单😁

既然栈我们写好了,那接下来我们来完成一道简单的算法题吧

一直一个字符串由"(","{","[","]",")","}"来组成,"("对应")","["对应"]",{""对应 "}",他们必须一一对应才是对的,比如“()[]”或者“{[()]}”这样的一一对应的才是对的,不然返回错误

这个就是典型的栈的思想了。“(”入栈, ")"出栈,最后相互抵消,如果栈的长度为0,就表明字符串是合法的,如果我这么说还没说清楚的话,接下来的代码你应该就能明白了

//定义一个工具方法
func compare(_ str: String) -> String {
    if str == "}" {
        return "{"
    } else if str == ")" {
        return "("
    } else if str == "]" {
        return "["
    } else {
        return ""
    }
}

使用工具方法进行比较

func validString(_ str: String) -> Bool {

    let arr = ["{", "[", "("]    
    var st: StringStack = StringStack()    
    for i in str {        
        if arr.contains(String(i)) {            
            st.push(String(i))           
             print("push进来了\(i)")        
        } else {        
         //当遍历到的字符是右括号,右中括号,右大括号的时候,那他的左边一定要是对应的左括号,左中括号,左大括号
           //而且那个正好是栈钉 ,如果是栈钉我们就pop,否则的话说明他的顺序是错的,不用再判断了,直接返回错误就行了
            if st.peek == compare(String(i)) {                
                print("pop出去了\(st.peek ?? ""),进来的是\(i)")                
                st.pop()            
            } else {                
                return false            
             }       
         }    
    }    
    return st.isEmpty
}

这样,我们通过栈也学习了去做一道算法题,也算是有些收获了。再见