import ( "strings" "strconv" ) func calculate(s string) int { s = strings.Replace(s, " ", "", -1) nums := make([]int, 0) ops := make([]byte, 0) l, m, n := len(s), 0, 0 beg := -1 push := false for i := 0; i < l; i++ { switch s[i] { case '+', '-': var num int if beg != -1 { num = atoi(s, beg, i) beg = -1 } else { num = nums[n-1] nums = nums[:n-1] n-- } if !push && m != 0 { // Pop aopb(&nums[n-1], ops[m-1], num) ops = ops[:m-1] m-- } else { nums = append(nums, num) n++ push = false } ops = append(ops, s[i]) m++ case '(': push = true case ')': var num int if beg != -1 { num = atoi(s, beg, i) beg = -1 } else { num = nums[n-1] nums = nums[:n-1] n-- } if m != 0 { // Handle expressions like (num) aopb(&nums[n-1], ops[m-1], num) ops = ops[:m-1] m-- } else { nums = append(nums, num) n++ } default: // Case '0', '1', ... , '9' if beg == -1 { beg = i } } } if beg != -1 { nums = append(nums, atoi(s, beg, l)) } if len(ops) != 0 { aopb(&nums[0], ops[0], nums[1]) } return nums[0] } func atoi(s string, beg, end int) int { i, _ := strconv.Atoi(s[beg:end]) return i } func aopb(a *int, op byte, b int) { switch op { case '+': *a += b case '-': *a -= b } }