package stack
import (
	"errors"
	"fmt"
)
type Stack struct {
	Element []interface{} //Element
}
func NewStack() *Stack {
	return &Stack{}
}
func (stack *Stack) Push(value ...interface{}) {
	stack.Element = append(stack.Element, value...)
}
//返回下一个元素
func (stack *Stack) Top() (value interface{}) {
	if stack.Size() > 0 {
		return stack.Element[stack.Size()-1]
	}
	return nil //read empty stack
}
//返回下一个元素,并从Stack移除元素
func (stack *Stack) Pop() (value interface{}) {
	if stack.Size() > 0 {
		d := stack.Element[stack.Size()-1]
		stack.Element = stack.Element[:stack.Size()-1]
		return d
	}
	return nil
}
//交换值
func (stack *Stack) Swap(other *Stack) {
	switch {
	case stack.Size() == 0 && other.Size() == 0:
		return
	case other.Size() == 0:
		other.Element = stack.Element[:stack.Size()]
		stack.Element = nil
	case stack.Size() == 0:
		stack.Element = other.Element
		other.Element = nil
	default:
		stack.Element, other.Element = other.Element, stack.Element
	}
	return
}
//修改指定索引的元素
func (stack *Stack) Set(idx int, value interface{}) (err error) {
	if idx >= 0 && stack.Size() > 0 && stack.Size() > idx {
		stack.Element[idx] = value
		return nil
	}
	return errors.New("Set失败!")
}
//返回指定索引的元素
func (stack *Stack) Get(idx int) (value interface{}) {
	if idx >= 0 && stack.Size() > 0 && stack.Size() > idx {
		return stack.Element[idx]
	}
	return nil //read empty stack
}
//Stack的size
func (stack *Stack) Size() int {
	return len(stack.Element)
}
//是否为空
func (stack *Stack) Empty() bool {
	if stack.Element == nil || stack.Size() == 0 {
		return true
	}
	return false
}
//打印
func (stack *Stack) Print() {
	for i := len(stack.Element) - 1; i >= 0; i-- {
		fmt.Println(i, "=>", stack.Element[i])
	}
}
package calculator
import (
	"calculator/stack"
	"strconv"
)
type Calculator struct{}
var DataStack *stack.Stack
var OperatorStack *stack.Stack
func NewCalculator() *Calculator {
	DataStack = stack.NewStack()
	OperatorStack = stack.NewStack()
	return &Calculator{}
}
func (c *Calculator) Cal(dataOrOperator string) int {
	if data, ok := strconv.ParseInt(dataOrOperator, 10, 64); ok == nil {
		//如果是数据直接入数据栈
		// fmt.Println(dataOrOperator)
		DataStack.Push(data)
	} else {
		//如果是操作符,和栈顶操作符比较优先级,如果大于栈顶,则直接入栈,否则栈顶元素出栈 进行操作
		if OperatorStack.Size() <= 0 {
			OperatorStack.Push(dataOrOperator)
		} else {
			//当前运算符的优先级
			currentOpePrecedence := operatorPrecedence(dataOrOperator)
			//当前运算符栈顶元素的优先级
			stackTopOpePrecedence := operatorPrecedence(OperatorStack.Top().(string))
			if currentOpePrecedence > stackTopOpePrecedence {
				//如果当前运算符的优先级大于栈顶元素的优先级,则入栈
				OperatorStack.Push(dataOrOperator)
			} else {
				//运算符栈顶元素出栈,数据栈出栈两个元素,然后进行运算
				stackOpe := OperatorStack.Pop()
				data2 := DataStack.Pop()
				data1 := DataStack.Pop()
				ret := calculateData(stackOpe.(string), data1.(int64), data2.(int64))
				DataStack.Push(ret)
				OperatorStack.Push(dataOrOperator)
			}
		}
	}
	return 0
}
func (c *Calculator) GetResult() int64 {
	var ret int64
	for {
		if OperatorStack.Size() > 0 {
			stackOpe := OperatorStack.Pop()
			data2 := DataStack.Pop()
			data1 := DataStack.Pop()
			ret = calculateData(stackOpe.(string), data1.(int64), data2.(int64))
			DataStack.Push(ret)
		} else {
			break
		}
	}
	return ret
}
func calculateData(operatorString string, data1, data2 int64) int64 {
	switch operatorString {
	case "+":
		return data1 + data2
	case "-":
		return data1 - data2
	case "*":
		return data1 * data2
	case "/":
		return data1 + data2
	default:
		return 0
	}
}
func operatorPrecedence(a string) int {
	i := 0
	switch a {
	case "+":
		i = 1
	case "-":
		i = 1
	case "*":
		i = 2
	case "/":
		i = 2
	}
	return i
}
package main
import (
	"calculator/calculator"
	"flag"
	"fmt"
)
var (
	inputStr = flag.String("input", "", "请输入...")
)
func main() {
	flag.Parse()
	var lstAllData []string
	var tempData string
	rs := []rune(*inputStr)
	for i := 0; i < len(rs); i++ {
		if string(rs[i]) == "+" || string(rs[i]) == "-" || string(rs[i]) == "*" || string(rs[i]) == "/" {
			lstAllData = append(lstAllData, tempData)
			lstAllData = append(lstAllData, string(rs[i]))
			tempData = ""
		} else {
			tempData += string(rs[i])
		}
		if i == len(rs)-1 {
			lstAllData = append(lstAllData, tempData)
		}
	}
	ca := calculator.NewCalculator()
	for _, v := range lstAllData {
		ca.Cal(v)
	}
	ret := ca.GetResult()
	fmt.Println(ret)
}
评论