Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to evaluate s-expression as string in Python
Suppose we have a string s as S-expression. We have to evaluate that S-expression and return result as integer. As we know that the S-expression is an expression which is either one number, or a recursive expression wrapped in parentheses like (+ (- 3 2) (* 3 3)), which indicates (3 - 2) + (3 * 3) = 10. Here valid operators are +, -, *, and /.
So, if the input is like s = "(- (+ 3 2) 2)", then the output will be 3, as ((3 + 2) - 2) = 3.
Algorithm Steps
To solve this, we will follow these steps ?
Create a new stack
Remove the opening and closing parentheses from s
Split s using spaces to make a list of tokens
-
Iterate through tokens in reverse order:
-
If token length > 1 (multi-digit number or negative number):
Push the integer value to stack
-
If token is a single digit:
Push the integer value to stack
-
If token is an operator (+, -, *, /):
Pop two numbers from stack
Perform the operation and push result back
-
Return the final result from stack
Example
Let us see the following implementation to get a better understanding ?
class Solution:
def solve(self, s):
stack = list()
s = s.replace("(", "")
s = s.replace(")", "")
tokens = s.split()
for i in tokens[::-1]:
if len(i) > 1:
if i[0] == "-":
stack.append(int(i))
continue
else:
stack.append(int(i))
elif i.isdigit():
stack.append(int(i))
else:
if len(stack) >= 2:
num1 = stack.pop()
num2 = stack.pop()
if i == "+":
stack.append(int(num1 + num2))
elif i == "-":
stack.append(int(num1 - num2))
elif i == "*":
stack.append(int(num1 * num2))
else:
stack.append(int(num1 / num2))
return stack.pop()
# Test the solution
ob = Solution()
s = "(- (+ 3 2) 2)"
print(ob.solve(s))
3
How It Works
The algorithm works by processing the S-expression in reverse order using a stack:
Parse tokens: Remove parentheses and split by spaces
Reverse processing: Process tokens from right to left
Stack operations: Numbers are pushed, operators pop two values and push the result
Final result: The stack contains the final evaluated result
Alternative Approach Using Recursion
Here's a more intuitive recursive solution ?
def evaluate_sexpression(s):
def parse(tokens, index):
if tokens[index[0]] != '(':
# It's a number
val = int(tokens[index[0]])
index[0] += 1
return val
# Skip opening parenthesis
index[0] += 1
operator = tokens[index[0]]
index[0] += 1
# Evaluate operands
operand1 = parse(tokens, index)
operand2 = parse(tokens, index)
# Skip closing parenthesis
index[0] += 1
# Apply operation
if operator == '+':
return operand1 + operand2
elif operator == '-':
return operand1 - operand2
elif operator == '*':
return operand1 * operand2
else: # operator == '/'
return operand1 // operand2
# Tokenize the expression
tokens = []
i = 0
while i < len(s):
if s[i] == ' ':
i += 1
elif s[i] in '()+-*/':
tokens.append(s[i])
i += 1
else:
# Parse number (could be negative)
j = i
if s[i] == '-':
i += 1
while i < len(s) and s[i].isdigit():
i += 1
tokens.append(s[j:i])
return parse(tokens, [0])
# Test the recursive solution
s = "(- (+ 3 2) 2)"
print(evaluate_sexpression(s))
3
Conclusion
S-expression evaluation can be solved using either a stack-based approach with reverse iteration or a recursive parsing method. The stack approach is more memory efficient, while recursion provides cleaner, more intuitive code that mirrors the nested structure of S-expressions.
