Skip to content

Commit 72948ba

Browse files
committed
add basic-calculator and basic-calculator-ii
1 parent c1602a2 commit 72948ba

File tree

4 files changed

+282
-0
lines changed

4 files changed

+282
-0
lines changed

go/basic-calculator-ii.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"strconv"
7+
)
8+
9+
func calculate2(s string) int {
10+
result := 0
11+
operation := '+'
12+
stack := make([]StackItem, 0, 10)
13+
hasInitial := false
14+
15+
for i := 0; i < len(s); i++ {
16+
if s[i] == ' ' {
17+
continue
18+
}
19+
if s[i] == '+' || s[i] == '-' {
20+
stack = append(stack, StackItem{result, rune(s[i])})
21+
result = 0
22+
operation = '+'
23+
hasInitial = false
24+
continue
25+
}
26+
if s[i] == '*' {
27+
operation = '*'
28+
continue
29+
}
30+
if s[i] == '/' {
31+
operation = '/'
32+
continue
33+
}
34+
end := parseInt(s, i)
35+
num, err := strconv.Atoi(s[i : end+1])
36+
if err != nil {
37+
fmt.Printf("%s %d %d\n", s, i, end)
38+
panic(err)
39+
}
40+
if !hasInitial {
41+
result = num
42+
i = end
43+
hasInitial = true
44+
}
45+
// fmt.Printf("%d %c %d\n", result, operation, num)
46+
47+
if operation == '*' {
48+
result *= num
49+
}
50+
if operation == '/' {
51+
result = int(math.Floor(float64(result) / float64(num)))
52+
}
53+
54+
i = end
55+
}
56+
stack = append(stack, StackItem{result, '='})
57+
result = 0
58+
operation = '+'
59+
for _, item := range stack {
60+
if operation == '+' {
61+
result += item.number
62+
}
63+
if operation == '-' {
64+
result -= item.number
65+
}
66+
operation = item.operation
67+
}
68+
// fmt.Printf("%v %d\n", stack, result)
69+
return result
70+
}

go/basic-calculator-ii_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package leetcode
2+
3+
import "testing"
4+
5+
func TestCalucate2(t *testing.T) {
6+
tests := []struct {
7+
input string
8+
expect int
9+
}{
10+
{
11+
input: "1+1",
12+
expect: 2,
13+
}, {
14+
input: "1-1",
15+
expect: 0,
16+
}, {
17+
input: " 1 + 1 ",
18+
expect: 2,
19+
}, {
20+
input: " 3/2 ",
21+
expect: 1,
22+
}, {
23+
input: " 2-1 + 2 ",
24+
expect: 3,
25+
}, {
26+
input: "3+2*2",
27+
expect: 7,
28+
}, {
29+
input: " 3+5 / 2 ",
30+
expect: 5,
31+
},
32+
}
33+
34+
for i, item := range tests {
35+
actual := calculate2(item.input)
36+
if actual != item.expect {
37+
t.Fatalf("%d, expect %d, actual %d\n", i, item.expect, actual)
38+
}
39+
}
40+
}

go/basic-calculator.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
)
7+
8+
type StackItem struct {
9+
number int
10+
operation rune
11+
}
12+
13+
func parseInt(s string, from int) int {
14+
if len(s) == 0 {
15+
return 0
16+
}
17+
for i := from; i < len(s); i++ {
18+
if s[i] >= '0' && s[i] <= '9' {
19+
continue
20+
}
21+
return i - 1
22+
}
23+
24+
return len(s) - 1
25+
}
26+
27+
func calculate(s string) int {
28+
result := 0
29+
hasInitial := false
30+
operation := '+'
31+
stack := make([]StackItem, 0, 10)
32+
stackTop := 0
33+
for i := 0; i < len(s); i++ {
34+
if s[i] == ' ' {
35+
continue
36+
}
37+
if s[i] == '(' {
38+
item := StackItem{result, operation}
39+
if stackTop == len(stack) {
40+
stack = append(stack, item)
41+
} else {
42+
stack[stackTop] = item
43+
}
44+
stackTop++
45+
result = 0
46+
hasInitial = false
47+
operation = '+'
48+
continue
49+
}
50+
if s[i] == ')' {
51+
if stackTop == 0 {
52+
continue
53+
}
54+
stackTop--
55+
item := stack[stackTop]
56+
// fmt.Printf("%v %d\n", item, result)
57+
if item.operation == '+' {
58+
result = item.number + result
59+
} else {
60+
result = item.number - result
61+
}
62+
hasInitial = true
63+
continue
64+
}
65+
if s[i] == '+' {
66+
operation = '+'
67+
continue
68+
}
69+
if s[i] == '-' {
70+
operation = '-'
71+
continue
72+
}
73+
end := parseInt(s, i)
74+
num, err := strconv.Atoi(s[i : end+1])
75+
if err != nil {
76+
fmt.Printf("%s %d %d\n", s, i, end)
77+
panic(err)
78+
}
79+
// fmt.Printf("%d %c %d\n", result, operation, num)
80+
if hasInitial {
81+
if operation == '+' {
82+
result += num
83+
}
84+
if operation == '-' {
85+
result -= num
86+
}
87+
} else {
88+
result = num
89+
hasInitial = true
90+
}
91+
92+
i = end
93+
}
94+
return result
95+
}

go/basic-calculator_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package leetcode
2+
3+
import "testing"
4+
5+
func TestParseInt(t *testing.T) {
6+
tests := []struct {
7+
input string
8+
from int
9+
expect int
10+
}{
11+
{
12+
input: "123",
13+
from: 0,
14+
expect: 2,
15+
}, {
16+
input: "1234",
17+
from: 1,
18+
expect: 3,
19+
}, {
20+
input: "1234 ",
21+
from: 1,
22+
expect: 3,
23+
}, {
24+
input: "",
25+
from: 0,
26+
expect: 0,
27+
}, {
28+
input: " 44 5",
29+
from: 1,
30+
expect: 2,
31+
},
32+
}
33+
34+
for i, item := range tests {
35+
actual := parseInt(item.input, item.from)
36+
if actual != item.expect {
37+
t.Fatalf("%d, expect %d, actual %d\n", i, item.expect, actual)
38+
}
39+
}
40+
}
41+
42+
func TestCalculate(t *testing.T) {
43+
tests := []struct {
44+
input string
45+
expect int
46+
}{
47+
{
48+
input: "1+1",
49+
expect: 2,
50+
}, {
51+
input: "(1+1)+(2+2)",
52+
expect: 6,
53+
}, {
54+
input: " 1 + 1 ",
55+
expect: 2,
56+
}, {
57+
input: " 1 + (1 + 1)",
58+
expect: 3,
59+
}, {
60+
input: " 2-1 + 2 ",
61+
expect: 3,
62+
}, {
63+
input: "2-(5-6)",
64+
expect: 3,
65+
}, {
66+
input: "(1+(4+5+2)-3)+(6+8)",
67+
expect: 23,
68+
},
69+
}
70+
71+
for i, item := range tests {
72+
actual := calculate(item.input)
73+
if actual != item.expect {
74+
t.Fatalf("%d, expect %d, actual %d\n", i, item.expect, actual)
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)