模擬棧&四則運算
尚硅谷Golang課
模擬棧&四則運算
//模擬棧的使用
type Stack struct {
MaxTop int //最大可存個數
Top int //頂
arr [20]int
}
func (s *Stack) Push(val int) (err error) {
//先判斷是否滿
if s.Top == s.MaxTop-1 {
fmt.Println("stack full")
return errors.New("stack full")
}
//放入數據
s.Top++
s.arr[s.Top] = val
return
}
func (s *Stack) Pop() (val int, err error) {
//先判斷是否空
if s.Top == -1 {
fmt.Println("stack empty")
return 0, errors.New("stack empty")
}
//彈出數據
val = s.arr[s.Top]
s.Top--
return val, nil
}
//遍歷
func (s *Stack) List() {
//先判斷是否空
if s.Top == -1 {
fmt.Println("stack empty")
return
}
fmt.Println("stack now=")
for i := s.Top; i >= 0; i-- {
fmt.Printf("arr[%d]=%d\n", i, s.arr[i])
}
}
//判斷字符是數字還運算符號
func (s *Stack) IsOper(val int) bool {
if val == 42 || val == 43 || val == 45 || val == 47 {
//ASC碼的+-*/
return true
} else {
return false
}
}
//運算
func (s *Stack) Cal(n1, n2, oper int) int {
res := 0
switch oper {
case 42:
res = n2 * n1
case 43:
res = n2 + n1
case 45:
res = n2 - n1
case 47:
res = n2 / n1
default:
fmt.Println("運算符號錯誤")
}
return res
}
//優先級
func (s *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() {
// stack := &Stack{
// MaxTop: 5, //最多存5個
// Top: -1, //表示棧為空
// }
// stack.Push(1)
// stack.Push(2)
// stack.Push(3)
// stack.Push(4)
// stack.Push(5)
// stack.Push(6)
// p1, _ := stack.Pop()
// fmt.Println("彈出", p1)
// p1, _ = stack.Pop()
// fmt.Println("彈出", p1)
// p1, _ = stack.Pop()
// fmt.Println("彈出", p1)
// p1, _ = stack.Pop()
// fmt.Println("彈出", p1)
// p1, _ = stack.Pop()
// fmt.Println("彈出", p1)
//四則運算練習
//數字棧
numStack := &Stack{
MaxTop: 20,
Top: -1,
}
//運算符號
operStack := &Stack{
MaxTop: 20,
Top: -1,
}
exp := "30+20*6+1"
n1 := 0
n2 := 0
oper := 0
res := 0
keepNum := ""
//定義一個index來掃描
index := 0
for {
ch := exp[index : index+1] //字符串
temp := int([]byte(ch)[0]) //對應的ASC碼
if operStack.IsOper(temp) { //說明是符號
if operStack.Top == -1 { //說明是空棧
operStack.Push(temp) //就入
} else {
if operStack.Priority(operStack.arr[operStack.Top]) >= operStack.Priority(temp) {
//比較一下棧頂的運算符號優先級,如果有先乘除的
n1, _ = numStack.Pop()
n2, _ = numStack.Pop()
oper, _ = operStack.Pop()
res = operStack.Cal(n1, n2, oper)
//算完塞回去
numStack.Push(res)
operStack.Push(temp)
} else {
operStack.Push(temp)
}
}
} else {
//處理多位數,看index後面是不是運算符號
//拼接
keepNum += ch
if index == len(exp)-1 { //如果已經到最後
val, _ := strconv.ParseInt(keepNum, 10, 64)
numStack.Push(int(val))
} else {
if operStack.IsOper(int([]byte(exp[index+1 : index+2])[0])) {
val, _ := strconv.ParseInt(keepNum, 10, 64)
numStack.Push(int(val))
keepNum = ""
}
}
//從ASC轉回數字
// val, _ := strconv.ParseInt(ch, 10, 64)
// numStack.Push(int(val))
}
//判斷是否繼續掃描
if index+1 == len(exp) {
break
}
index++
}
for {
if operStack.Top == -1 {
break
}
n1, _ = numStack.Pop()
n2, _ = numStack.Pop()
oper, _ = operStack.Pop()
res = operStack.Cal(n1, n2, oper)
//算完塞回去
numStack.Push(res)
}
final, _ := numStack.Pop()
fmt.Printf("算式%s=%v", exp, final)
}
上次修改於 2021-09-01
此篇文章的評論功能已經停用。