🚀 本题 LeetCode 传送门

    题目大意

    实现一个基本的计算器来计算一个简单的字符串表达式的值。字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。

    解题思路

    • 注意点一:算式中有空格,需要跳过
    • 注意点二:算式中会出现负数,负负得正的情况需要特殊处理,所以需要记录每次计算出来的符号

    代码

    1. package leetcode
    2. import (
    3. "container/list"
    4. "fmt"
    5. "strconv"
    6. )
    7. // 解法一
    8. func calculate(s string) int {
    9. i, stack, result, sign := 0, list.New(), 0, 1 // 记录加减状态
    10. for i < len(s) {
    11. if s[i] == ' ' {
    12. i++
    13. } else if s[i] <= '9' && s[i] >= '0' { // 获取一段数字
    14. base, v := 10, int(s[i]-'0')
    15. for i+1 < len(s) && s[i+1] <= '9' && s[i+1] >= '0' {
    16. v = v*base + int(s[i+1]-'0')
    17. i++
    18. }
    19. result += v * sign
    20. i++
    21. } else if s[i] == '+' {
    22. sign = 1
    23. i++
    24. } else if s[i] == '-' {
    25. sign = -1
    26. i++
    27. } else if s[i] == '(' { // 把之前计算结果及加减状态压栈,开始新的计算
    28. stack.PushBack(result)
    29. stack.PushBack(sign)
    30. result = 0
    31. sign = 1
    32. i++
    33. } else if s[i] == ')' { // 新的计算结果 * 前一个加减状态 + 之前计算结果
    34. result = result*stack.Remove(stack.Back()).(int) + stack.Remove(stack.Back()).(int)
    35. i++
    36. }
    37. }
    38. return result
    39. }
    40. // 解法二
    41. func calculate1(s string) int {
    42. stack := []byte{}
    43. for i := 0; i < len(s); i++ {
    44. if s[i] == ' ' {
    45. continue
    46. } else if s[i] == ')' {
    47. tmp, index := "", len(stack)-1
    48. for ; index >= 0; index-- {
    49. if stack[index] == '(' {
    50. break
    51. }
    52. }
    53. tmp = string(stack[index+1:])
    54. stack = stack[:index]
    55. res := strconv.Itoa(calculateStr(tmp))
    56. for j := 0; j < len(res); j++ {
    57. stack = append(stack, res[j])
    58. }
    59. } else {
    60. stack = append(stack, s[i])
    61. }
    62. }
    63. fmt.Printf("stack = %v\n", string(stack))
    64. return calculateStr(string(stack))
    65. }
    66. func calculateStr(str string) int {
    67. s, nums, tmpStr, res := []byte{}, []int{}, "", 0
    68. // 处理符号的问题,++得+,--得+,+-、-+得-
    69. for i := 0; i < len(str); i++ {
    70. if len(s) > 0 && s[len(s)-1] == '+' && str[i] == '+' {
    71. continue
    72. } else if len(s) > 0 && s[len(s)-1] == '+' && str[i] == '-' {
    73. s[len(s)-1] = '-'
    74. } else if len(s) > 0 && s[len(s)-1] == '-' && str[i] == '+' {
    75. continue
    76. } else if len(s) > 0 && s[len(s)-1] == '-' && str[i] == '-' {
    77. s[len(s)-1] = '+'
    78. } else {
    79. s = append(s, str[i])
    80. }
    81. }
    82. str = string(s)
    83. s = []byte{}
    84. for i := 0; i < len(str); i++ {
    85. if isDigital(str[i]) {
    86. tmpStr += string(str[i])
    87. } else {
    88. num, _ := strconv.Atoi(tmpStr)
    89. nums = append(nums, num)
    90. tmpStr = ""
    91. s = append(s, str[i])
    92. }
    93. }
    94. if tmpStr != "" {
    95. num, _ := strconv.Atoi(tmpStr)
    96. nums = append(nums, num)
    97. }
    98. res = nums[0]
    99. for i := 0; i < len(s); i++ {
    100. if s[i] == '+' {
    101. res += nums[i+1]
    102. } else {
    103. res -= nums[i+1]
    104. }
    105. }
    106. fmt.Printf("s = %v nums = %v res = %v\n", string(s), nums, res)
    107. return res
    108. }
    109. func isDigital(v byte) bool {
    110. if v >= '0' && v <= '9' {
    111. return true
    112. }
    113. return false
    114. }