227.basic-calculator-ii.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import (
  2. "strconv"
  3. "strings"
  4. )
  5. func calculate(s string) int {
  6. none := struct{}{}
  7. opsSet := map[byte]struct{}{'+': none, '-': none, '*': none, '/': none}
  8. ops := make([]byte, 0)
  9. nums := make([]int, 0)
  10. prev := -1
  11. for i := range s {
  12. if _, ok := opsSet[s[i]]; ok {
  13. num, _ := strconv.Atoi(strings.Trim(s[prev+1:i], " ")) // Atoi should trim all spaces of string
  14. mulOrDiv(&nums, &ops, &num)
  15. nums = append(nums, num)
  16. ops = append(ops, s[i])
  17. prev = i
  18. }
  19. }
  20. num, _ := strconv.Atoi(strings.Trim(s[prev+1:], " "))
  21. mulOrDiv(&nums, &ops, &num)
  22. nums = append(nums, num)
  23. for left, right := 0, len(nums)-1; left < right; left, right = left+1, right-1 {
  24. nums[left], nums[right] = nums[right], nums[left]
  25. } // Reverse nums and ops
  26. for left, right := 0, len(ops)-1; left < right; left, right = left+1, right-1 {
  27. ops[left], ops[right] = ops[right], ops[left]
  28. }
  29. for l1, l2 := len(nums), len(ops); l1 != 1; l1, l2 = l1-1, l2-1 {
  30. op := ops[l2-1]
  31. ops = ops[:l2-1]
  32. n1, n2 := nums[l1-2], nums[l1-1]
  33. nums = nums[:l1-2]
  34. switch op {
  35. case '+':
  36. nums = append(nums, n2+n1)
  37. case '-':
  38. nums = append(nums, n2-n1)
  39. }
  40. }
  41. return nums[0]
  42. }
  43. func mulOrDiv(nums *[]int, ops *[]byte, num *int) {
  44. if l := len(*ops); l != 0 && ((*ops)[l-1] == '*' || (*ops)[l-1] == '/') {
  45. n := (*nums)[len(*nums)-1]
  46. *nums = (*nums)[:len(*nums)-1]
  47. switch (*ops)[l-1] {
  48. case '*':
  49. *num = n * (*num)
  50. case '/':
  51. *num = n / (*num)
  52. }
  53. *ops = (*ops)[:l-1]
  54. }
  55. }