package main
import (
"fmt"
"strconv"
"strings"
)
type Node struct {
data interface{}
next *Node
}
type LinkedStack struct {
length int
head *Node
}
func NewLinkedStack() LinkedStack {
return LinkedStack{length: 0, head: nil}
}
func (s *LinkedStack) Clear() {
s.length = 0
s.head = nil
}
func (s *LinkedStack) Empty() bool {
return s.head == nil
}
func (s *LinkedStack) Get() interface{} {
if s.Empty() {
panic("栈为空")
}
return s.head.data
}
func (s *LinkedStack) Push(data interface{}) {
newNode := Node{
data: data,
}
if !s.Empty() {
newNode.next = s.head
}
s.head = &newNode
s.length++
}
func (s *LinkedStack) Pop() interface{} {
if s.Empty() {
panic("栈为空")
}
data := s.head.data
s.head = s.head.next
s.length--
return data
}
func (s *LinkedStack) Length() int {
return s.length
}
func elemExist(s string, l []string) bool {
for _, v := range l {
if v == s {
return true
}
}
return false
}
func priorityExp(s string, stack *LinkedStack) (sList []string) {
if s == ")" {
for {
if stack.Empty() {
break
}
cur := stack.Pop()
if cur == "(" {
return
}
sList = append(sList, cur.(string))
}
} else if s == "+" || s == "-" {
for {
if stack.Empty() {
break
}
if stack.Get() == "(" {
break
}
sList = append(sList, stack.Pop().(string))
}
} else {
for {
if stack.Empty() {
break
}
if stack.Get() != "/" || stack.Get() != "*" {
break
}
sList = append(sList, stack.Pop().(string))
}
}
stack.Push(s)
return
}
func InvPolSufExp(expression string) string {
stack := NewLinkedStack()
strs := make([]string, 0)
for _, v := range strings.Split(expression, " ") {
if elemExist(v, []string{"+", "-", "*", "/", "(", ")"}) == false {
strs = append(strs, v)
} else {
strs = append(strs, priorityExp(v, &stack)...)
}
}
for {
if stack.Empty() {
break
}
strs = append(strs, stack.Pop().(string))
}
return strings.Join(strs, " ")
}
func Arithmetic(expStr string) float64 {
stack := NewLinkedStack()
for _, v := range strings.Split(expStr, " ") {
if elemExist(v, []string{"+", "-", "*", "/", "(", ")"}) == false {
var vv interface{} = v
stack.Push(vv)
} else {
num1, _ := strconv.ParseFloat(stack.Pop().(string), 64)
num2, _ := strconv.ParseFloat(stack.Pop().(string), 64)
var num float64
switch v {
case "+":
num = num2 + num1
case "-":
num = num2 - num1
case "*":
num = num2 * num1
case "/":
num = num2 / num1
}
var numRes interface{} = fmt.Sprintf("%v", num)
stack.Push(numRes)
}
}
res, _ := strconv.ParseFloat(stack.Pop().(string), 64)
return res
}
func main() {
fmt.Println(Arithmetic(InvPolSufExp("9 + ( 3 - 1 ) * 3 + 10 / 2")))
}