forked from yuyongwei/Algorithms-In-Swift
-
Notifications
You must be signed in to change notification settings - Fork 1
/
basicCalculator.swift
101 lines (79 loc) · 2.28 KB
/
basicCalculator.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .
Example 1:
Input: "1 + 1"
Output: 2
Example 2:
Input: " 2-1 + 2 "
Output: 3
Example 3:
Input: "(1+(4+5+2)-3)+(6+8)"
Output: 23
Note:
* You may assume that the given expression is always valid.
* Do not use the eval built-in library function.
*/
func calculate(_ s: String) -> Int {
let cs: [Character] = Array(s)
let ss = cs.map { String($0) }
var operators = [String]() // operator stack
var nums = [Int]() // numbers stack
var current: Int = -1
for i in 0..<ss.count { // numbers
if let n = Int(ss[i]) {
if current == -1 { current = n}
else { current = current * 10 + n }
} else if ss[i] == " " {
continue
} else {// operators
if current != -1 {
nums.append(current)
current = -1
}
// calculate
if let op = operators.last, op != "(", ss[i] != "(" {
operators.popLast()
if let b = nums.popLast(), let a = nums.popLast() {
nums.append(eval(a, b, op))
}
}
if ss[i] == ")" {
operators.popLast()
} else {
operators.append(ss[i])
}
}
}
if current != -1 { nums.append(current) }
if operators.count > 0 {
if let op = operators.last {
operators.popLast()
if let b = nums.popLast(), let a = nums.popLast() {
nums.append(eval(a, b, op))
}
}
}
return nums.last!
}
func eval(_ a: Int, _ b: Int, _ op: String) -> Int {
var result: Int
if op == "+" {
result = a + b
} else if op == "-" {
result = a - b
} else {
result = 0
}
return result
}
// Test Cases
calculate("1")
calculate("123")
calculate("1 + 1")
calculate("2-1 + 2")
calculate("10+11")
calculate("(1+(4+5+2)-3)+(6+8)")
calculate("1-(3-5)")
calculate("(123)")
calculate("1-(3+5-2+(3+19-(3-1-4+(9-4-(4-(1+(3)-2)-5)+8-(3-5)-1)-4)-5)-4+3-9)-4-(3+2-5)-10")