12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- import (
- "strconv"
- "strings"
- )
- func calculate(s string) int {
- none := struct{}{}
- opsSet := map[byte]struct{}{'+': none, '-': none, '*': none, '/': none}
- ops := make([]byte, 0)
- nums := make([]int, 0)
- prev := -1
- for i := range s {
- if _, ok := opsSet[s[i]]; ok {
- num, _ := strconv.Atoi(strings.Trim(s[prev+1:i], " ")) // Atoi should trim all spaces of string
- mulOrDiv(&nums, &ops, &num)
- nums = append(nums, num)
- ops = append(ops, s[i])
- prev = i
- }
- }
- num, _ := strconv.Atoi(strings.Trim(s[prev+1:], " "))
- mulOrDiv(&nums, &ops, &num)
- nums = append(nums, num)
- for left, right := 0, len(nums)-1; left < right; left, right = left+1, right-1 {
- nums[left], nums[right] = nums[right], nums[left]
- } // Reverse nums and ops
- for left, right := 0, len(ops)-1; left < right; left, right = left+1, right-1 {
- ops[left], ops[right] = ops[right], ops[left]
- }
- for l1, l2 := len(nums), len(ops); l1 != 1; l1, l2 = l1-1, l2-1 {
- op := ops[l2-1]
- ops = ops[:l2-1]
- n1, n2 := nums[l1-2], nums[l1-1]
- nums = nums[:l1-2]
- switch op {
- case '+':
- nums = append(nums, n2+n1)
- case '-':
- nums = append(nums, n2-n1)
- }
- }
- return nums[0]
- }
- func mulOrDiv(nums *[]int, ops *[]byte, num *int) {
- if l := len(*ops); l != 0 && ((*ops)[l-1] == '*' || (*ops)[l-1] == '/') {
- n := (*nums)[len(*nums)-1]
- *nums = (*nums)[:len(*nums)-1]
- switch (*ops)[l-1] {
- case '*':
- *num = n * (*num)
- case '/':
- *num = n / (*num)
- }
- *ops = (*ops)[:l-1]
- }
- }
|