开发者学堂课程【Go 语言核心编程 - 数据结构和算法:数据结构和算法—栈的计算表达式(3)(一)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/627/detail/9858
数据结构和算法—栈的计算表达式(3)(一)
内容介绍:
一、处理 for 循环
二、最终逻辑
一、处理 for 循环
上节我们已经讲了三个重要的工具方法:判断一个字符是不是一个运算符[+,-,*,/]、运算的方法、判断某个运算符的优先级
接着继续刚才内容进行讲解:
for{
ch := exp[index:index+1]
}
现在进行扫描,扫描出的是一个单个字符的字符串,即这个字符串里面只有一个字符。
然后进行判断,在扫描到后判断首先是不是一个数字,再判断是否是操作符,如果是一个操作符当然就不是一个数字。即只需要判断判断是不是一个操作符。
判断是否是一个操作符使用第一组判断运算符的方法
func(this *Stack)IsOper(val int) bool {}
但是要传进去的是一个 valve,怎么把字符转成对应的int值?比如扫描到如下
ch ==>”+”
字符串是一个加号,那么现在就要将+转换为43
在代码
for{
ch:=exp[index:index+1] //字符串.
}
中加入temp:=int([]byte(ch)[0])
//先转换成一个 byte 切片,取第一个,转成int值
字符和 byte 是一个对应关系,先转成一个 byte 切片。现在是加号,就会将里面的加号转成 byte 。
然后要取的是第一个,取完之后还需要再转换成int。temp 就是43,类型就是 int。
如果不转成 int 就是单个的 byte,也无法传入。这个就是字符对应的 ASCiI 码值。
接下来再 if,在 if 里面调用方法,目前写的方法都是与栈相连的,使用哪个栈的实例来调用都可以。使用数栈或者符号栈都可以,现在以符号栈为例来调用方法
输入代码if operStack.IsOper(temp)
{
//说明是符号
}else{//说明是数
numStack.Push(temp)
}
如果是符号,又分两个逻辑
if operStack.IsOper(temp){//说明是符号
//如果是 operStack 是一个空栈,直接入栈
if operStack.Top == - 1{//空栈
operStack.Push(temp)
}else{
}
}
如果不是一个空栈也要分逻辑:
如果发现 operStack 栈顶的运算符的优先级大于等于当前准备入栈的运算符的优先级,就从符号栈 pop 出,并从数栈也 pop 两个数,进行运算,运算后的结果再重新入栈到数栈,当前符号再入符号栈
否则,
运算符就直接入栈
if operStack.IsOper(temp){//说明是符号
//如果是 operStack 是一个空栈,直接入栈
if operStack.Top == - 1{//空栈
operStack.Push(temp)
}else{
if operStack.Priority(operStack.arr[operStack.Top]) >=
operStack.Priority(temp){
}
}
}
里为了配合运算,我们定义需要的变量,在代码index:=0
下添加代码:
num1 :=0 num2 :=0 oper :=0 result :=0
然后继续在代码中输入:
else{
if operStack.Priority(operStack.arr[operStack.Top]) >=
operStack.Priority(temp){
num1,_ = numStack.Pop() //pop 会弹两个数,忽略掉 error
num2,_ = numStack.Pop()
oper,_ = operStack.Pop()
result = operStack.Cal(num1,num2,oper)
//将计算结果重新入栈
numStack.Push(result)
//当前的符号压入符号栈
operStack.Push(temp)
}else{
operStack.Push(temp)
//operStack 栈顶的运算符的优先级小于当前准备入栈的运算符的优先级
}
}
逻辑分析完后还存在一个问题,原代码中 for 中有代码:
ch:=exp[index:index+1]
这里只取到一个,也就是取完一个后对 temp 符号做完处理就运行。还需要往下继续扫描。
在代码 else{
//说明是数}逻辑下添加代码:
//继续扫描
//继续往下扫描就是 index++,但是 index__可能到达极限。所以要先判断 index 是否已经扫描到计算表达式的最后
if index + 1==len(exp){
break
}
index++
//扫描到最后就 break,否则就 index++继续扫描