Help please. I want to make an expression analysis calculator using the reverse Polish Notation (Reverse Polish NOTATION). I need to do so that if the user has entered the wrong expression to inform about it. I do not need to catch mistakes and just print “Error”
I made 2 stack (because it is a stack calculator)
struct doublestack {
Var Items = [Double] ()
Mutating Func Push (_ Item: Double) {
Items.APPEND (Item)
}
Mutating Func Pop () - & gt; Double {
Return Items.Removelast ()
}
Mutating Func Empty () - & gt; BOOL {
If Items.Count == 0 {
Return True.
} else {
Return False.
}
}
Mutating Func Peek () - & gt; Double {
RETURN ITEMS.LAST!
}
}
Struct CharactersStack {
Var Items = [Character] ()
Mutating Func Push (_ Item: Character) {
Items.APPEND (Item)
}
Mutating Func Pop () - & gt; Character {
Return Items.Removelast ()
}
Mutating Func Empty () - & gt; BOOL {
If Items.Count == 0 {
Return True.
} else {
Return False
}
}
Mutating Func Peek () - & gt; Character {
RETURN ITEMS.LAST!
}
}
My expressional expression parsing features and rpntoanswer.
Func Isoper (C: Character) - & gt; BOOL {
IF C == "+" || C == "-" || C == "*" || C == "/" || C == "^" || C == "×" || C == "÷" || C == "%" {
Return True.
}
Return False.
}
FUNC GETP (Token: Character) - & gt; Int8 {
If token == "+" || Token == "-" {
Return 1.
} ELSE If TKen == "*" || token == "/" || token == "×" || token == "÷" || token == "%" {
Return 2.
} ELSE if token == "^" {
Return 3.
}
Return 0.
}
FUNC ExpressionTorpn (EXPR: [Character]) Throws - & GT; [Character] {
Var Current = [Character] ()
Var Stack = CharactersStack ()
VAR i: int = 0
While I & LT; EXPR.COUNT {
IF Expr [i] == "-" {
IF i == 0 || EXPR [I - 1] == "(" {
CURRENT.APPEND ("(")
CURRENT.APPEND (EXPR [I])
i = i + 1
While Expr [i] .isnumber || EXPR [i] == "." {
CURRENT.APPEND (EXPR [I])
I + = 1
}
current.append (")")
Current.append ("")
}
}
If EXPR [i] .ISNumber {
While (EXPR [i] .ISNumber || Expr [i] == ".") {
CURRENT.APPEND (EXPR [I])
I + = 1
}
Current.append ("")
}
IF Expr [i] == "(" {
Stack.push (EXPR [I])
}
IF Expr [i] == ")" {
While! stack.empty () & amp; & amp; stack.peek ()! = "(" {
current.append (stack.pop ())
Current.append ("")
}
stack.pop ()
}
IF Isoper (C: EXPR [I]) {
While! stack.empty () & amp; & amp; GetP (Token: EXPR [i]) & lt; = getp (token: stack.peek ()) & amp; & amp; stack.peek ()! = "(" {
current.append (stack.pop ())
Current.append ("")
}
Stack.push (EXPR [I])
}
I + = 1
}
While (! stack.empty ()) {
current.append (stack.pop ())
Current.append ("")
}
Return Current
}
FUNC RPNToANSWER (RPN: [Character]) Throws - & gt; Double {
VAR Operand = [Character] ()
Var Stack = DoubleStack ()
VAR i: int = 0
While I & LT; RPN.COUNT {
Operand = []
IF RPN [i] == "" {
I + = 1
Continue.
}
IF RPN [i] .ISNumber || RPN [i] == "." {
While RPN [i] .isnumber || RPN [i] == "." {
Operand.APPEND (RPN [i])
I + = 1
}
Stack.Push (Double (String (Operand))!)
Continue.
}
IF GetP (Token: RPN [i]) & gt; 0 {
Let A: Double = stack.pop ()
Let B: Double = Stack.pop ()
IF RPN [i] == "+" {
Stack.push (A + B)
} ELSE IF RPN [I] == "-" {
Stack.push (B - a)
} ELSE IF RPN [i] == "*" || rpn [i] == "×" {
Stack.push (b * a)
} ELSE IF RPN [I] == "/" || RPN [i] == "÷" {
Stack.push (b / a)
} ELSE IF RPN [I] == "%" {
Stack.push (A * B / 100)
} ELSE IF RPN [i] == "^" {
Stack.push (POW (B, A))
}
}
I + = 1
}
Return Stack.pop ()
}
And finally, what I want to withdraw
var r: string = "(11 + 222-111 +)"
var str: [character] = r.compactmap {$ 0}
do {
Let EXPRTORPN = Try ExpressionTorpn (EXPR: STR)
Let Answer = Try RPNToANSWER (RPN: Exprtorpn)
PRINT (ANSWER)
} Catch {
Print ("Error !!!!!!!")
}
I get an error
Thread 1: Fatal Error: CAN’t Remove Last Element from An Empty Collection
In the Return Items.Removelast ()
line
mutating func pop () - & gt; Double {
Return Items.Removelast ()
}
How can I get out to the “Error” to the Console if the code collapses?
Thank you in advance !!!
Answer 1, Authority 100%
Use the documentation. And this is not sarcasm, this is the only actual source of truth for the developer. To begin with, simply select the removelast ()
(CMD-Click) method and see what is written:
Collection should not be empty. Accordingly, if you want to use a do-try-catch, you need to make it so that the error is thrown away.
// describe the errors that are planned
ENUM CALCULATIONERROR: ERROR {
Case emptycollection
}
// rewrite your method so that it discardes the error:
FUNC POP () Throws - & gt; Double {
Guard! Items.isempty else {
Throw CalculationError.EmptyCollection
}
Return Items.Removelast ()
}
and use it already try ...
Similarly with the rest.