数据结构之栈


阅读目录

一、栈介绍

二、栈应用

一、栈介绍

二、栈应用

计算表达式

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
}

原文地址:https://www.cnblogs.com/zhangliang91/p/11716441.html