Go_栈

1. 栈的介绍

2. 栈的应用

3. 栈入门
package main import (
"fmt"
"errors"
) //使用数组来模拟一个栈的使用
type Stack struct {
MaxTop int // 表示我们栈最大可以存放数个数
Top int // 表示栈顶, 因为栈顶固定,因此我们直接使用Top
arr [5]int // 数组模拟栈
} //入栈
func (this *Stack) Push(val int) (err error) { //先判断栈是否满了
if this.Top == this.MaxTop-1 {
fmt.Println("stack full")
return errors.New("stack full")
}
this.Top++
//放入数据
this.arr[this.Top] = val
return
} //出栈
func (this *Stack) Pop() (val int, err error) {
//判断栈是否空
if this.Top == -1 {
fmt.Println("stack empty!")
return 0, errors.New("stack empty")
} //先取值,再 this.Top--
val = this.arr[this.Top]
this.Top--
return val, nil } //遍历栈,注意需要从栈顶开始遍历
func (this *Stack) List() {
//先判断栈是否为空
if this.Top == -1 {
fmt.Println("stack empty")
return
}
fmt.Println("栈的情况如下:")
for i := this.Top; i >= 0; i-- {
fmt.Printf("arr[%d]=%d\n", i, this.arr[i])
} } func main() { stack := &Stack{
MaxTop: 5, // 表示最多存放5个数到栈中
Top: -1, // 当栈顶为-1,表示栈为空
} //入栈
stack.Push(1)
stack.Push(2)
stack.Push(3)
stack.Push(4)
stack.Push(5) //显示
stack.List()
val, _ := stack.Pop()
fmt.Println("出栈val=", val) // 5
//显示
stack.List() // fmt.Println()
val, _ = stack.Pop()
val, _ = stack.Pop()
val, _ = stack.Pop()
val, _ = stack.Pop()
val, _ = stack.Pop() // 出错
fmt.Println("出栈val=", val) // 5
//显示
stack.List() //
}
4. 栈的计算表达式
package main
import (
"fmt"
"errors"
"strconv"
) //使用数组来模拟一个栈的使用
type Stack struct {
MaxTop int // 表示我们栈最大可以存放数个数
Top int // 表示栈顶, 因为栈顶固定,因此我们直接使用Top
arr [20]int // 数组模拟栈
}
//入栈
func (this *Stack) Push(val int) (err error) { //先判断栈是否满了
if this.Top == this.MaxTop - 1 {
fmt.Println("stack full")
return errors.New("stack full")
}
this.Top++
//放入数据
this.arr[this.Top] = val
return
} //出栈
func (this *Stack) Pop() (val int, err error) {
//判断栈是否空
if this.Top == -1 {
fmt.Println("stack empty!")
return 0, errors.New("stack empty")
} //先取值,再 this.Top--
val = this.arr[this.Top]
this.Top--
return val, nil }
//遍历栈,注意需要从栈顶开始遍历
func (this *Stack) List() {
//先判断栈是否为空
if this.Top == -1 {
fmt.Println("stack empty")
return
}
fmt.Println("栈的情况如下:")
for i := this.Top; i >= 0; i-- {
fmt.Printf("arr[%d]=%d\n", i, this.arr[i])
} }
//判断一个字符是不是一个运算符[+, - , * , /]
func (this *Stack) IsOper(val int) bool { if val == 42 || val == 43 || val == 45 || val == 47 {
return true
} else {
return false
}
} //运算的方法
func (this *Stack) Cal(num1 int, num2 int, oper int) int{
res := 0
switch oper {
case 42 :
res = num2 * num1
case 43 :
res = num2 + num1
case 45 :
res = num2 - num1
case 47 :
res = num2 / num1
default :
fmt.Println("运算符错误.")
}
return res
} //编写一个方法,返回某个运算符的优先级[程序员定义]
//[* / => 1 + - => 0]
func (this *Stack) Priority(oper int) int {
res := 0
if oper == 42 || oper == 47 {
res = 1
} else if oper == 43 || oper == 45 {
res = 0
}
return res
} func main() { //数栈
numStack := &Stack{
MaxTop : 20,
Top : -1,
}
//符号栈
operStack := &Stack{
MaxTop : 20,
Top : -1,
} exp := "30+30*6-4-6"
//定义一个index ,帮助扫描exp
index := 0
//为了配合运算,我们定义需要的变量
num1 := 0
num2 := 0
oper := 0
result := 0
keepNum := "" for {
//这里我们需要增加一个逻辑,
//处理多位数的问题
ch := exp[index:index+1] // 字符串.
//ch ==>"+" ===> 43
temp := int([]byte(ch)[0]) // 就是字符对应的ASCiI码
if operStack.IsOper(temp) { // 说明是符号 //如果operStack 是一个空栈, 直接入栈
if operStack.Top == -1 { //空栈
operStack.Push(temp)
}else {
//如果发现opertStack栈顶的运算符的优先级大于等于当前准备入栈的运算符的优先级
//,就从符号栈pop出,并从数栈也pop 两个数,进行运算,运算后的结果再重新入栈
//到数栈, 当前符号再入符号栈
if operStack.Priority(operStack.arr[operStack.Top]) >=
operStack.Priority(temp) {
num1, _ = numStack.Pop()
num2, _ = numStack.Pop()
oper, _ = operStack.Pop()
result = operStack.Cal(num1,num2, oper)
//将计算结果重新入数栈
numStack.Push(result)
//当前的符号压入符号栈
operStack.Push(temp) }else {
operStack.Push(temp)
} } } else { //说明是数 //处理多位数的思路
//1.定义一个变量 keepNum string, 做拼接
keepNum += ch
//2.每次要向index的后面字符测试一下,看看是不是运算符,然后处理
//如果已经到表达最后,直接将 keepNum
if index == len(exp) - 1 {
val, _ := strconv.ParseInt(keepNum, 10, 64)
numStack.Push(int(val))
} else {
//向index 后面测试看看是不是运算符 [index]
if operStack.IsOper(int([]byte(exp[index+1:index+2])[0])) {
val, _ := strconv.ParseInt(keepNum, 10, 64)
numStack.Push(int(val))
keepNum = ""
}
}
} //继续扫描
//先判断index是否已经扫描到计算表达式的最后
if index + 1 == len(exp) {
break
}
index++ } //如果扫描表达式 完毕,依次从符号栈取出符号,然后从数栈取出两个数,
//运算后的结果,入数栈,直到符号栈为空
for {
if operStack.Top == -1 {
break //退出条件
}
num1, _ = numStack.Pop()
num2, _ = numStack.Pop()
oper, _ = operStack.Pop()
result = operStack.Cal(num1,num2, oper)
//将计算结果重新入数栈
numStack.Push(result) } //如果我们的算法没有问题,表达式也是正确的,则结果就是numStack最后数
res, _ := numStack.Pop()
fmt.Printf("表达式%s = %v", exp, res)
}
Go_栈的更多相关文章
- 通往全栈工程师的捷径 —— react
腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...
- Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)
--reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...
- duang~免费的学习视频来啦:学霸君之全栈测试
学霸君向童鞋们推荐一款 同名学霸学习 视频教程 重点是完全免费收看学习噢!!! 今天 学霸君推荐腾讯课堂的学霸君之全栈测试 复制下方链接至腾讯课堂中报名学习 https://ke.qq.com/cou ...
- [数据结构]——链表(list)、队列(queue)和栈(stack)
在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂! Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 90 Solved: 46[Submit][Status][Discu ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- .NET全栈开发工程师学习路径
PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...
- Nodejs之MEAN栈开发(八)---- 用户认证与会话管理详解
用户认证与会话管理基本上是每个网站必备的一个功能.在Asp.net下做的比较多,大体的思路都是先根据用户提供的用户名和密码到数据库找到用户信息,然后校验,校验成功之后记住用户的姓名和相关信息,这个信息 ...
随机推荐
- 记录 Docker 的学习过程 (网络篇)
打开2个会话,分别运行以下命令 # docker run -it -P --name nginx2 nginx #-P 端口随机映射 再打开一个会话查看 运行中的容器 # docker ps -aCO ...
- 关于Git的右键菜单消失的处理
右键菜单 Git Bash Here window + R,输入regedit回车进入注册表 进入如下目录 HKEY_CLASSES_ROOT\Directory\Background\shell 在 ...
- 搭建 Review Board - SVN 审核工具
一.安装环境 CentOS-6.7,ReviewBoard-2.5.1.1 二.安装环境的配置 1.确认当前系统中有如下包,若没有,使用yum安装 httpd-2.2.15:httpd 指的是apac ...
- python3练习100题——030
这周开始,要重新振作一点吧! 如果每天都想着消费升级,而不是想着如何投入时间精力让自己进步,未来根本就看不到希望. 我想要更认真的活着 live wild 原题链接:http://www.runoob ...
- Vue之生命周期activated与created使用
created activated 触发顺序 组件创建最初始 created => mounted =>activated 触发次数 只在组件刚创建时创建 在使用keep-alive标 ...
- Windows ThinPC 7 部署后续设置与本地化
还原注销背景 %system32%\oobe\info\backgrounds 删除该目录下所有文件后变为wes7背景 24时制与非UNICODE字符乱码解决 Control Panel \ Regi ...
- OpenGL 编程指南 (2)
1.OpenGL对共享的边有严格的规定:1)共享边上的像素因为同事被两者所覆盖,因此不可能不受到光照计算的影响: 2)共享边上的像素值,不可能受到多于一个三角形的光照计算的影响. 2.多边形存在正面与 ...
- Spring Cloud介绍
Spring Cloud中国社区博客 Spring Cloud发展到2016年,国内关注的人越来越多,但是相应学习交流的平台和材料比较分散,不利于学习交流,因此Spring Cloud中国社区应运而生 ...
- 13-Java-JSP知识梳理
一.JSP了解 JSP(java server pages,服务器页面),可理解为HTML+ Java = = JSP,它可生成动态的HTML(拼标签).是以.jsp为后缀的文件, 内容是以标签为主体 ...
- 剑指offer 面试题. 按之字形顺序打印二叉树
题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 方法1: 正常层次遍历,利用普通队列.逢 ...
