224.basic-calculator.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import (
  2. "strings"
  3. "strconv"
  4. )
  5. func calculate(s string) int {
  6. s = strings.Replace(s, " ", "", -1)
  7. nums := make([]int, 0)
  8. ops := make([]byte, 0)
  9. l, m, n := len(s), 0, 0
  10. beg := -1
  11. push := false
  12. for i := 0; i < l; i++ {
  13. switch s[i] {
  14. case '+', '-':
  15. var num int
  16. if beg != -1 {
  17. num = atoi(s, beg, i)
  18. beg = -1
  19. } else {
  20. num = nums[n-1]
  21. nums = nums[:n-1]
  22. n--
  23. }
  24. if !push && m != 0 { // Pop
  25. aopb(&nums[n-1], ops[m-1], num)
  26. ops = ops[:m-1]
  27. m--
  28. } else {
  29. nums = append(nums, num)
  30. n++
  31. push = false
  32. }
  33. ops = append(ops, s[i])
  34. m++
  35. case '(':
  36. push = true
  37. case ')':
  38. var num int
  39. if beg != -1 {
  40. num = atoi(s, beg, i)
  41. beg = -1
  42. } else {
  43. num = nums[n-1]
  44. nums = nums[:n-1]
  45. n--
  46. }
  47. if m != 0 { // Handle expressions like (num)
  48. aopb(&nums[n-1], ops[m-1], num)
  49. ops = ops[:m-1]
  50. m--
  51. } else {
  52. nums = append(nums, num)
  53. n++
  54. }
  55. default: // Case '0', '1', ... , '9'
  56. if beg == -1 {
  57. beg = i
  58. }
  59. }
  60. }
  61. if beg != -1 {
  62. nums = append(nums, atoi(s, beg, l))
  63. }
  64. if len(ops) != 0 {
  65. aopb(&nums[0], ops[0], nums[1])
  66. }
  67. return nums[0]
  68. }
  69. func atoi(s string, beg, end int) int {
  70. i, _ := strconv.Atoi(s[beg:end])
  71. return i
  72. }
  73. func aopb(a *int, op byte, b int) {
  74. switch op {
  75. case '+': *a += b
  76. case '-': *a -= b
  77. }
  78. }