1.栈的定义
栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
栈是一种后进先出的数据结构。
允许插入和删除的一段称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表。关于栈顶和栈底如图所示:
2.栈的应用
2.1 如:IDE的撤销,
2.2 如:多级函数的调用(函数A运行的时候调用函数B,此时系统栈会记录函数A的运行记录A2,函数B运行的时候出现了函数C,系统栈再次入栈B2,等函数C运行完成之后,系统栈先取出栈B2,等运行完函数B以后,取出栈A2,最终运行完函数A)
2.3 如:IDE中括号的匹配 "{[()]}"等,(出现左括号的时候依次入栈,如出现右括号,取出栈顶元素,检测是否匹配)
3.代码的实现
3.1go的stack实现
由于go中1没有stack包的支持,那么我们只能简单的先自己写了,其实也是很简单的,代码如下:
package arr
import "log"
/**
* 栈的基本操作
*/
type Stack struct {
B []interface{}
}
/**
* push向栈中添加数据
* @e int
*/
func (s *Stack) Push(value interface{}) []interface{} {
s.B = append(s.B, value)
return s.B
}
/**
* Pop从栈中取出数据
*/
func (s *Stack) Pop() []interface{} {
if len(s.B) == 0 {
log.Fatal("错误:slice不得为空")
}
s.B = s.B[:len(s.B)-1]
return s.B
}
调用main.go
package main
import (
"./arr"
"fmt"
)
func main() {
var a arr.Stack
fmt.Println(a.Push(1))
fmt.Println(a.Push(156156))
fmt.Println(a.Pop())
fmt.Println(a.Pop())
}
3.2 IDE中括号匹配的代码实现
package arr
import "log"
/**
* 栈的基本操作
*/
type Stack struct {
B []interface{}
}
/**
* push向栈中添加数据
* @e int
*/
func (s *Stack) Push(value interface{}) []interface{} {
s.B = append(s.B, value)
return s.B
}
/**
* Pop从栈中取出数据
*/
func (s *Stack) Pop() []interface{} {
if len(s.B) == 0 {
log.Fatal("错误:slice不得为空")
}
s.B = s.B[:len(s.B)-1]
return s.B
}
/**
* Top从栈中取出栈顶
*/
func (s *Stack) Top() interface{} {
if len(s.B) == 0 {
log.Fatal("错误:slice不得为空")
}
top := s.B[len(s.B)-1]
s.B = s.B[:len(s.B)-1]
return top
}
main.go
package main
import (
"./arr"
"fmt"
)
func main() {
kuo := "{[()(){[()()][()()]}][()()]}"
var a arr.Stack
for i := 0; i < len(kuo); i++ {
if kuo[i:i+1] == "{" || kuo[i:i+1] == "[" || kuo[i:i+1] == "(" {
//入栈
//fmt.Println("分解:", kuo[i:i+1])
a.Push(kuo[i : i+1])
} else {
//出栈并对比
if kuo[i:i+1] == ")" && a.Top() != "(" {
fmt.Println("()匹配失败")
}
if kuo[i:i+1] == "]" && a.Top() != "[" {
fmt.Println("[]匹配失败")
}
if kuo[i:i+1] == "}" && a.Top() != "{" {
fmt.Println("{}匹配失败")
}
}
}
//查看栈顶是否还有字符
if len(a.B) == 0 {
fmt.Println("匹配成功")
} else {
fmt.Println("匹配失败")
}
}