• Go语言(Golang)用栈计算算数表达式的结果


    package main
    
    import (
    	"fmt"
    	"errors"
    	"strconv"
    )
    
    //用栈计算算数算数表达式的结果
    
    type Stack struct {
    	MaxSize int
    	Top int
    	Array [20]int
    }
    
    //入栈
    func (this *Stack) Push(val int) error {
    	if this.IsFull() {
    		return errors.New("该栈已满!")
    	}
    	this.Top++
    	this.Array[this.Top] = val
    	return nil
    }
    
    //出栈
    func (this *Stack) Pop() (val int, err error) {
    	if this.IsEmpty() {
    		return 0, errors.New("该栈已空!")
    	}
    	val = this.Array[this.Top]
    	this.Top--
    	return val, nil
    }
    
    //判断栈已满
    func (this *Stack) IsFull() bool {
    	return this.Top == this.MaxSize - 1
    }
    
    //判断该栈为空
    func (this *Stack) IsEmpty() bool {
    	return this.Top == -1
    }
    
    //显示栈里的值
    func (this *Stack) List() {
    	if this.IsEmpty() {
    		fmt.Println("该栈为空!")
    		return
    	}
    	for i := this.Top; i >= 0; i-- {
    		fmt.Printf("%d	",this.Array[i])
    	}
    }
    
    
    //判断如果不是运算符就是数字
    //如果是运算符返回true,是数字返回false
    //*,+,-,/ 运算发依次对应的ASCII码为42,43,45,47
    func (this *Stack) IsOper(val int) bool {
    	return val == 42 || val == 43 || val == 45 || val == 47
    }
    
    //判断运算符的优先级
    func (this *Stack) Priority(val int) int {
    	if val == 23 || val == 45 {
    		return 0
    	} else if val == 42 || val == 47 {
    		return 1
    	} else {
    		return -1
    	}
    }
    
    //将从栈里弹出的两个数和运算符进行计算
    func (this *Stack) Cal(a, b , oper int) int {
    	switch oper {
    	case 42:
    		return b * a
    	case 43:
    		return b + a
    	case 45:
    		return b - a
    	case 47:
    		return b / a
    	default:
    		return 0
    	}
    }
    
    
    func main() {
    	//数字的栈
    	number := &Stack {
    		MaxSize : 20,
    		Top : -1,
    	}
    	//运算符的栈
    	oper := &Stack {
    		MaxSize : 20,
    		Top : -1,
    	}
    
    	fmt.Println("请输入你要计算的算数表达式(仅支持+,-,*,/):")
    	var expr string
    	fmt.Scan(&expr)
    	//字符串expr的下标
    	index := 0
    	operTemp := 0
    	keepNum := ""
    	for {
    		str := expr[index:index+1]
    
    		operTemp = int([]byte(str)[0])
    		//判断是运算符还是数字
    		if oper.IsOper(operTemp) {
    			//如果运算符栈里没有值,就直接入栈
    			if oper.Top == -1 {
    				oper.Push(operTemp)
    			} else {
    				//如果栈里已有运算符则判断两个运算符的优先级
    				if oper.Priority(oper.Array[oper.Top]) >= oper.Priority(operTemp) {
    					//从数字栈弹出两个数
    					a,_ := number.Pop()
    					b,_ := number.Pop()
    					//从运算符栈弹出一个运算符
    					c,_ := oper.Pop()
    					//将运算的结果重新入数字栈
    					number.Push(number.Cal(a, b, c))
    					//将运算符入栈
    					oper.Push(operTemp)
    				} else {
    					oper.Push(operTemp)
    				}
    			}
    		} else {
    			keepNum += str
    			//如果index==len(expr)则表示expr已读到最后,直接入数字栈
    			if index == len(expr) - 1 {
    				data,_ := strconv.ParseInt(keepNum,10, 64)
    				number.Push(int(data))
    			} else {
    				//判断str后一位是不是运算符,如果是就直接入数字栈,如果不是keepNum就拼接str
    				if oper.IsOper(int([]byte(expr[index+1:index+2])[0])) {
    					data,_ := strconv.ParseInt(keepNum,10, 64)
    					number.Push(int(data))
    					keepNum = ""
    				}
    			}
    		}
    		index++
    		if index == len(expr) {
    			break
    		}
    	}
    
    	//将数字栈里的数依次弹出两个,运算符栈弹出一个 依次计算
    	for {
    		//运算符栈为空时推出
    		if oper.Top == -1 {
    			break
    		}
    		a,_ := number.Pop()
    		b,_ := number.Pop()
    		c,_ := oper.Pop()
    		number.Push(number.Cal(a, b, c))
    	}
    	res,_ := number.Pop()
    	fmt.Printf("%s=%d",expr,res)
    }
    

      

  • 相关阅读:
    WAP协议研究笔记—彩信的传输
    应用程序重起自身等几则技巧
    谁妨碍了我们快乐
    国庆长假总结
    关于输入法的两个问题
    反刍
    为什么,一个思维方式的问题,一个习惯的问题,已经意识到了这一点,
    电影池子,
    幻想下,
    意识流,
  • 原文地址:https://www.cnblogs.com/HouZhenglan/p/10097467.html
Copyright © 2020-2023  润新知