|
|
@@ -0,0 +1,58 @@
|
|
|
+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]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|