1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| package calculation
import ( "fmt" "strconv" )
var operatorPriority = map[string]int{ "+": 0, "-": 0, "*": 1, "/": 1, "(": 2, ")": 2, }
type Calculator struct { nums *StackInt operators *Stack exp string }
func NewCalculator(exp string) *Calculator { return &Calculator{ nums: NewStackInt(), operators: NewStack(), exp: exp, } }
func (c *Calculator) Calculate() int { l := len(c.exp) for i := 0; i < l; i++ { switch e := (c.exp[i]); e { case ' ': continue case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': j := i for j < l && c.exp[j] <= '9' && c.exp[j] >= '0' { j++ } n, _ := strconv.Atoi(c.exp[i:j]) i = j - 1 c.nums.Push(n) case '+', '-', '*', '/': pre := c.operators.Pop() for pre != "" && pre != "(" && operatorPriority[string(e)] <= operatorPriority[pre] { c.nums.Push(c.calc(pre)) pre = c.operators.Pop() } if pre != "" { c.operators.Push(pre) } c.operators.Push(string(e)) case '(': c.operators.Push(string(e)) case ')': for o := c.operators.Pop(); o != "(" && o != ""; o = c.operators.Pop() { c.nums.Push(c.calc(o)) } default: panic("invalid exp") } } o := c.operators.Pop() if o == "" { return c.nums.Pop() } return c.calc(o) }
func (c *Calculator) calc(o string) int { b := c.nums.Pop() a := c.nums.Pop()
fmt.Printf("%d %s %d\n", a, o, b)
switch o { case "+": return a + b case "-": return a - b case "*": return a * b case "/": return a / b }
return 0 }
func calculate(s string) int { return NewCalculator(s).Calculate() }
|