栈的结构其实挺简单的,就一句话先进后出,而且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
}这样,我们通过栈也学习了去做一道算法题,也算是有些收获了。再见