zoukankan      html  css  js  c++  java
  • 数据结构之栈


    阅读目录

    一、栈介绍

    二、栈应用

    一、栈介绍

    二、栈应用

    计算表达式

    package main
    
    import (
    	"errors"
    	"fmt"
    	"strconv"
    )
    
    type Stack struct {
    	maxTop int
    	top    int
    	arr    [20]int //数组
    }
    
    func (this *Stack) Push(val int) (err error) {
    	// 首先判断栈已满
    	if this.top == this.maxTop-1 {
    		return errors.New("stack full")
    	}
    	// top++ -> 移动top值
    	this.top++
    	this.arr[this.top] = val
    	return
    }
    
    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]=%v", i, this.arr[i])
    	}
    }
    
    func (this *Stack) Pop() (val int, err error) {
    	if this.top == -1 {
    		fmt.Println("stack empty")
    		return -1, errors.New("stack empty")
    	}
    	val = this.arr[this.top]
    	this.top-- // 移动栈顶
    	return val, nil
    }
    
    func main() {
    	//数字栈
    	numStack := &Stack{
    		maxTop: 20,
    		top:    -1,
    	}
    	//符号栈
    	operStack := &Stack{
    		maxTop: 20,
    		top:    -1,
    	}
    	exp := "3+20*12-2"
    	// 定义一个index,帮助扫描exp
    	index := 0
    	num1 := 0
    	num2 := 0
    	oper := 0
    	keepNum := "" // 拼接字符串
    
    	for {
    		//处理多位数问题
    		ch := exp[index : index+1]
    		tmp := int([]byte(ch)[0]) //转为ascii值
    		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() //取出栈顶元素1
    					num2, _ = numStack.Pop() //取出栈顶元素2
    					//先处理大的优先级
    					oper, _ = operStack.Pop()                 //取出符号元素
    					newVal := operStack.Cal(num1, num2, oper) //计算
    					_ = numStack.Push(newVal)                 // 计算值写入栈
    					//新的表达式入栈
    					_ = operStack.Push(tmp)
    				} else {
    					//第二种情况
    					_ = operStack.Push(tmp)
    				}
    			}
    
    		} else {
    			//拼接
    			keepNum += ch
    			// 如果已经到表达式最后
    			if index == len(exp)-1 {
    				numVal, _ := strconv.ParseInt(keepNum, 10, 64)
    				_ = numStack.Push(int(numVal))
    			} else {
    				//如果不是最后  向index后字符探测一位
    				if operStack.isOper(int([]byte(exp[index+1 : index+2])[0])) {
    					numVal, _ := strconv.ParseInt(keepNum, 10, 64)
    					_ = numStack.Push(int(numVal))
    					keepNum = "" //清空标记
    				}
    			}
    		}
    
    		//继续扫描
    		if index+1 != len(exp) {
    			index++
    		} else {
    			break
    		}
    	}
    
    	// 最后一步处理出栈计算
    	for {
    		if operStack.top == -1 {
    			break
    		}
    		num1, _ = numStack.Pop() //取出栈顶元素1
    		num2, _ = numStack.Pop() //取出栈顶元素2
    		//先处理大的优先级
    		oper, _ = operStack.Pop()                //取出符号元素
    		newVal := numStack.Cal(num1, num2, oper) //计算
    		_ = numStack.Push(newVal)                // 计算值写入栈
    	}
    
    	// 结束后  栈中只存在最后一个计算值
    	result, _ := numStack.Pop()
    	fmt.Println("计算的值为:", result)
    
    }
    
    //
    func (this *Stack) isOper(val int) bool {
    	// 42->*  43->
    	if val == 42 || val == 43 || val == 45 || val == 47 {
    		return true
    	}
    	return false
    }
    
    //计算方法
    func (this *Stack) Cal(num1, num2, oper int) int {
    	res := 0
    	switch oper {
    	case 42:
    		res = num2 * num1
    	case 43:
    		res = num1 + num2
    	case 45:
    		res = num2 - num1
    	case 47:
    		res = num2 / num1
    	default:
    		fmt.Println("运算符错误", oper)
    	}
    	return res
    }
    
    //返回优先级方法   +- => 0  */ => 1
    func (this *Stack) Priority(oper int) int {
    	if oper == 42 || oper == 47 {
    		return 1
    	} else if oper == 43 || oper == 45 {
    		return 0
    	}
    	return -1
    }
    
    
  • 相关阅读:
    常用连链接命令行存储小工具
    switch case 跳转表
    抖音越狱版本App下载
    AutoLayout + UILabel布局
    ReplayKit2 有线投屏项目-反向Socket实现
    ReplayKit2 有线投屏项目总结
    直播相关-搭建直播流服务器nodejs
    难过!失眠!
    CAShapeLayer
    WebService相关概念介绍
  • 原文地址:https://www.cnblogs.com/zhangliang91/p/11716441.html
Copyright © 2011-2022 走看看