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
    }
    
    
  • 相关阅读:
    模板 无源汇上下界可行流 loj115
    ICPC2018JiaozuoE Resistors in Parallel 高精度 数论
    hdu 2255 奔小康赚大钱 最佳匹配 KM算法
    ICPC2018Beijing 现场赛D Frog and Portal 构造
    codeforce 1175E Minimal Segment Cover ST表 倍增思想
    ICPC2018Jiaozuo 现场赛H Can You Solve the Harder Problem? 后缀数组 树上差分 ST表 口胡题解
    luogu P1966 火柴排队 树状数组 逆序对 离散化
    luogu P1970 花匠 贪心
    luogu P1967 货车运输 最大生成树 倍增LCA
    luogu P1315 观光公交 贪心
  • 原文地址:https://www.cnblogs.com/zhangliang91/p/11716441.html
Copyright © 2011-2022 走看看