前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang数据结构之利用栈求计算表达式(加减乘除)

golang数据结构之利用栈求计算表达式(加减乘除)

作者头像
西西嘛呦
发布2020-08-26 14:59:06
7560
发布2020-08-26 14:59:06
举报

例如:3+2*6-2

先定义两个栈,一个为数值栈,一个为运算符栈;

stack.go

package stack

import (
    "errors"
    "fmt"
)

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("栈满了")
        return errors.New("栈满了")
    }
    s.Top++
    s.Arr[s.Top] = val
    return
}

func (s *Stack) Pop() (val int, err error) {
    if s.Top == -1 {
        fmt.Println("栈已空")
        return -1, errors.New("栈已空")
    }
    val = s.Arr[s.Top]
    s.Arr[s.Top] = 0
    s.Top--
    return val, nil

}

func (s *Stack) Show() {
    if s.Top == -1 {
        fmt.Println("栈为空")
        return
    }
    tmp := s
    for i := tmp.Top; i >= 0; i-- {
        fmt.Printf("Arr[%d]=%v\n", i, tmp.Arr[i])
    }
    return
}

//判断一个字符是数字还是加减乘除
func (s *Stack) IsOper(val int) bool {
    if val == 42 || val == 43 || val == 45 || val == 47 {
        return true
    } else {
        return false
    }
}

//运算的方法
func (s *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
}

//定义优先级
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
}

main.go

package main

import (
    "fmt"
    "go_code/data_structure/stack"
    "strconv"
)

func main() {

    str := "30+2*6-600/2"
    n := len(str)
    numStack := &stack.Stack{
        MaxTop: n,
        Top:    -1,
    }
    operStack := &stack.Stack{
        MaxTop: n,
        Top:    -1,
    }
    index := 0
    num1 := 0
    num2 := 0
    oper := 0
    result := 0
    keepNum := ""
    for {
        ch := str[index : index+1]
        //字符对应的ASCII码值
        tmp := int([]byte(ch)[0])
        if operStack.IsOper(tmp) {
            if operStack.Top == -1 {
                operStack.Push(tmp)
            } else {
                //判断栈顶的优先级
                if operStack.Priority(operStack.Arr[operStack.Top]) >=
                    operStack.Priority(tmp) {
                    num1, _ = numStack.Pop()
                    num2, _ = numStack.Pop()
                    oper, _ = operStack.Pop()
                    result = operStack.Cal(num1, num2, oper)
                    //将计算的结果重新入栈
                    numStack.Push(result)
                    //当前符号重新入栈
                    operStack.Push(tmp)
                } else {
                    operStack.Push(tmp)
                }
            }

        } else {
            //判断型如30等数字
            keepNum += ch

            if index == n-1 {
                val, _ := strconv.ParseInt(keepNum, 10, 64)
                numStack.Push(int(val))
            } else {
                //向index后面探以位
                if operStack.IsOper(int([]byte(str[index+1 : index+2])[0])) {
                    val, _ := strconv.ParseInt(keepNum, 10, 64)
                    numStack.Push(int(val))
                    keepNum = ""
                }
            }
            //入栈的数要是int型
            // val, _ := strconv.ParseInt(ch, 10, 64)
            // numStack.Push(int(val))
        }
        if index == n-1 {
            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)
    }

    res, _ := numStack.Pop()
    fmt.Printf("计算表达式 %v 的值是:%v\n", str, res)
}

运行结果:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-12-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档