Get Value from Parenthesis
Last Updated :
11 Dec, 2025
We are given a parenthesis string s consisting of '(', ')', and integers (where each integer lies in the range -10⁹ to 10⁹). Our task is to evaluate the value of this string by following these rules:
- There is always an integer between an opening and a closing parenthesis.
- Any expression of the form (x) evaluates to the absolute value of x.
- If there are consecutive balanced parenthesis, then we must alternately add and subtract their evaluated values.
For example, if the string is (x)(y)((z)), then its value will be: (value of (x)) - (value of (y)) + (value of ((z))).
Examples:
Input: s = "(((1)))"
Output: 1
Explanation: Steps:
(((1))) = ((abs(1))) = ((1))
((1)) = (abs(1)) = (1)
(1) = abs(1) =1
Input: s = "((-1)(3))"
Output: 2
Explanation: Steps:
((-1)(3)) = (abs(-1) - abs(3)) = (1 - 3) = (-2)
(-2) = abs(-2) = 2
[Naive Approach] Substring + Recursion — O(n^2) Time and O(n) Space
In this approach, the string is scanned repeatedly to identify and evaluate every balanced parenthesis substring separately. For nested structures, the same inner parts are recalculated multiple times using recursion. After extracting all individual values, they are combined using the alternating addition and subtraction rule.
C++
#include <iostream>
#include <vector>
using namespace std;
// Helper function to trim spaces from both ends of a substring
string trim(string &s, int l, int r) {
// Move left index to the first non-space character
while (l <= r && isspace(s[l])) l++;
// Move right index to the last non-space character
while (r >= l && isspace(s[r])) r--;
if (l > r) return "";
return s.substr(l, r - l + 1);
}
int evalBrute(string &s, int l, int r) {
// Check whether the current substring contains any parentheses
bool hasParen = false;
for (int i = l; i <= r; i++) {
if (s[i] == '(' || s[i] == ')') {
hasParen = true;
break;
}
}
// If no parentheses are found, this substring is a plain number
if (!hasParen) {
// Remove extra spaces
string t = trim(s, l, r);
if (t.empty()) return 0;
return stoi(t);
}
vector<int> vals;
int i = l;
while (i <= r) {
if (s[i] == '(') {
int start = i;
int bal = 0;
int end = i;
// Find the matching ')' for this '('
for (int j = i; j <= r; j++) {
if (s[j] == '(') bal++;
else if (s[j] == ')') bal--;
// When balance becomes zero, we found the matching ')'
if (bal == 0) {
end = j;
break;
}
}
// Recursively evaluate inside the current "( ... )"
int inner = evalBrute(s, start + 1, end - 1);
int groupVal = abs(inner);
vals.push_back(groupVal);
i = end + 1;
}
else {
// Skip non-parenthesis characters
i++;
}
}
// Apply alternating sum rule: + - + - ...
int res = 0;
int sign = 1;
for (int v : vals) {
res += sign * v;
sign = -sign;
}
return res;
}
int getValue(string s) {
return evalBrute(s, 0, (int)s.size() - 1);
}
int main() {
string s = "((-1)(3))";
int ans = getValue(s);
cout << ans << endl;
return 0;
}
Java
import java.util.ArrayList;
public class GFG {
// Helper function to trim spaces from both ends of a substring
static String trim(String s, int l, int r) {
// Move left index to the first non-space character
while (l <= r && Character.isWhitespace(s.charAt(l))) l++;
// Move right index to the last non-space character
while (r >= l && Character.isWhitespace(s.charAt(r))) r--;
if (l > r) return "";
return s.substring(l, r + 1);
}
static int evalBrute(String s, int l, int r) {
// Check whether the current substring contains any parentheses
boolean hasParen = false;
for (int i = l; i <= r; i++) {
if (s.charAt(i) == '(' || s.charAt(i) == ')') {
hasParen = true;
break;
}
}
// If no parentheses are found, this substring is a plain number
if (!hasParen) {
// Remove extra spaces
String t = trim(s, l, r);
if (t.isEmpty()) return 0;
return Integer.parseInt(t);
}
ArrayList<Integer> vals = new ArrayList<>();
int i = l;
while (i <= r) {
if (s.charAt(i) == '(') {
int start = i;
int bal = 0;
int end = i;
// Find the matching ')' for this '('
for (int j = i; j <= r; j++) {
char c = s.charAt(j);
if (c == '(') bal++;
else if (c == ')') bal--;
// When balance becomes zero, we found the matching ')'
if (bal == 0) {
end = j;
break;
}
}
// Recursively evaluate inside the current "( ... )"
int inner = evalBrute(s, start + 1, end - 1);
int groupVal = Math.abs(inner);
vals.add(groupVal);
i = end + 1;
}
else {
// Skip non-parenthesis characters
i++;
}
}
// Apply alternating sum rule: + - + - ...
int res = 0;
int sign = 1;
for (int v : vals) {
res += sign * v;
sign = -sign;
}
return res;
}
static int getValue(String s) {
return evalBrute(s, 0, s.length() - 1);
}
public static void main(String[] args) {
String s = "((-1)(3))";
int ans = getValue(s);
System.out.println(ans);
}
}
Python
# Helper function to trim spaces from both ends of a substring
def trim(s, l, r):
# Move left index to the first non-space character
while l <= r and s[l].isspace():
l += 1
# Move right index to the last non-space character
while r >= l and s[r].isspace():
r -= 1
if l > r:
return ""
return s[l:r+1]
def evalBrute(s, l, r):
# Check whether the current substring contains any parentheses
hasParen = any(c in "()"
for c in s[l:r+1])
# If no parentheses are found, this substring is a plain number
if not hasParen:
t = trim(s, l, r) # Remove extra spaces
if t == "":
return 0
return int(t)
vals = []
i = l
while i <= r:
if s[i] == '(':
start = i
bal = 0
end = i
# Find the matching ')' for this '('
for j in range(i, r + 1):
if s[j] == '(':
bal += 1
elif s[j] == ')':
bal -= 1
# When balance becomes zero, we found the matching ')'
if bal == 0:
end = j
break
# Recursively evaluate inside the current "( ... )"
inner = evalBrute(s, start + 1, end - 1)
vals.append(abs(inner))
i = end + 1
else:
# Skip non-parenthesis characters
i += 1
# Apply alternating sum rule: + - + - ...
res = 0
sign = 1
for v in vals:
res += sign * v
sign *= -1
return res
def getValue(s):
return evalBrute(s, 0, len(s) - 1)
if __name__ == "__main__":
s = "((-1)(3))"
print(getValue(s))
C#
using System;
using System.Collections.Generic;
class GFG {
// Helper function to trim spaces from both ends of a substring
static string Trim(string s, int l, int r) {
// Move left index to the first non-space character
while (l <= r && Char.IsWhiteSpace(s[l])) l++;
// Move right index to the last non-space character
while (r >= l && Char.IsWhiteSpace(s[r])) r--;
if (l > r) return "";
return s.Substring(l, r - l + 1);
}
static int evalBrute(string s, int l, int r) {
// Check whether the current substring contains any parentheses
bool hasParen = false;
for (int i = l; i <= r; i++) {
if (s[i] == '(' || s[i] == ')') {
hasParen = true;
break;
}
}
// If no parentheses are found, this substring is a plain number
if (!hasParen) {
string t = Trim(s, l, r); // Remove extra spaces
if (t == "") return 0;
return int.Parse(t);
}
List<int> vals = new List<int>();
int idx = l;
while (idx <= r) {
if (s[idx] == '(') {
int start = idx;
int bal = 0;
int end = idx;
// Find the matching ')' for this '('
for (int j = idx; j <= r; j++) {
if (s[j] == '(') bal++;
else if (s[j] == ')') bal--;
// When balance becomes zero, we found the matching ')'
if (bal == 0) {
end = j;
break;
}
}
// Recursively evaluate inside the current "( ... )"
int inner = evalBrute(s, start + 1, end - 1);
vals.Add(Math.Abs(inner));
idx = end + 1;
}
else {
// Skip non-parenthesis characters
idx++;
}
}
// Apply alternating sum rule: + - + - ...
int res = 0;
int sign = 1;
foreach (int v in vals) {
res += sign * v;
sign = -sign;
}
return res;
}
static int getValue(string s) {
return evalBrute(s, 0, s.Length - 1);
}
static void Main() {
string s = "((-1)(3))";
int ans = getValue(s);
Console.WriteLine(ans);
}
}
JavaScript
// Helper function to trim spaces from both ends of a substring
function trimStr(s, l, r) {
// Move left index to the first non-space character
while (l <= r && s[l] === ' ') l++;
// Move right index to the last non-space character
while (r >= l && s[r] === ' ') r--;
if (l > r) return "";
return s.substring(l, r + 1);
}
// Recursive brute force on substring s[l..r]
function evalBrute(s, l, r) {
// Check whether the current substring contains any parentheses
let hasParen = false;
for (let i = l; i <= r; i++) {
if (s[i] === '(' || s[i] === ')') {
hasParen = true;
break;
}
}
// If no parentheses are found, this substring is a plain number
if (!hasParen) {
let t = trimStr(s, l, r);
if (t.length === 0) return 0;
return parseInt(t);
}
let vals = [];
let i = l;
while (i <= r) {
if (s[i] === '(') {
let start = i;
let bal = 0;
let end = i;
// Find the matching ')' for this '('
for (let j = i; j <= r; j++) {
if (s[j] === '(') bal++;
else if (s[j] === ')') bal--;
if (bal === 0) {
end = j;
break;
}
}
// Recursively evaluate inside the current "( ... )"
let inner = evalBrute(s, start + 1, end - 1);
let groupVal = Math.abs(inner);
vals.push(groupVal);
i = end + 1;
} else {
i++; // Skip non-parenthesis characters
}
}
// Apply alternating sum rule: + - + - ...
let res = 0;
let sign = 1;
for (let v of vals) {
res += sign * v;
sign = -sign;
}
return res;
}
function getValue(s) {
return evalBrute(s, 0, s.length - 1);
}
//Driver Code
let s = "((-1)(3))";
let ans = getValue(s);
console.log(ans);
[Optimal Approach 1] Recursive Parsing with Index — O(n) Time and O(n) Space
This approach processes the string from left to right using recursion. Whenever an opening bracket is found, the function recursively evaluates the content inside it until the matching closing bracket. If the content is a number, its absolute value is taken. If it contains inner parentheses, they are solved first before applying the absolute value. At each level, consecutive groups are combined using alternating + and -.
C++
#include <iostream>
#include <vector>
#include <cctype>
#include <cmath>
using namespace std;
int parseExpr(string &s, int &i);
// Skips all whitespace characters starting from index i
void skipSpaces(string &s, int &i) {
while (i < (int)s.size() && isspace(s[i]))
i++;
}
// Parses a signed integer starting at index i
int parseNumber(string &s, int &i) {
skipSpaces(s, i);
int sign = 1;
// Handle optional sign
if (i < (int)s.size() && (s[i] == '+' || s[i] == '-')) {
if (s[i] == '-') sign = -1;
i++;
}
int num = 0;
while (i < (int)s.size() && isdigit(s[i])) {
num = num * 10 + (s[i] - '0');
i++;
}
return sign * num;
}
// Parses exactly one "( ... )" group and returns its value
int parseGroup(string &s, int &i) {
skipSpaces(s, i);
// Current character must be '('
i++;
skipSpaces(s, i);
int innerVal;
// If next part starts with '(' again, it is a nested expression
if (i < (int)s.size() && s[i] == '(')
innerVal = parseExpr(s, i);
else
innerVal = parseNumber(s, i);
skipSpaces(s, i);
// Skip closing ')'
if (i < (int)s.size() && s[i] == ')')
i++;
// Apply absolute value for this group
return abs(innerVal);
}
int parseExpr(string &s, int &i) {
vector<int> vals;
skipSpaces(s, i);
// Read consecutive groups until we hit ')' or reach the end
while (i < (int)s.size()) {
skipSpaces(s, i);
if (i >= (int)s.size() || s[i] != '(')
break;
int v = parseGroup(s, i);
vals.push_back(v);
skipSpaces(s, i);
}
// Apply alternating sum: + - + - ...
int res = 0;
int sign = 1;
for (int v : vals) {
res += sign * v;
sign = -sign;
}
return res;
}
int getValue(string s) {
int i = 0;
return parseExpr(s, i);
}
int main() {
string s = "((-1)(3))";
int ans = getValue(s);
cout << ans << endl;
return 0;
}
Java
import java.util.ArrayList;
class GFG {
// Skips all whitespace characters starting from index i
static void skipSpaces(String s, int[] i) {
while (i[0] < s.length() && Character.isWhitespace(s.charAt(i[0])))
i[0]++;
}
// Parses a signed integer starting at index i
static int parseNumber(String s, int[] i) {
skipSpaces(s, i);
int sign = 1;
// Handle optional sign
if (i[0] < s.length() && (s.charAt(i[0]) == '+' || s.charAt(i[0]) == '-')) {
if (s.charAt(i[0]) == '-') sign = -1;
i[0]++;
}
int num = 0;
while (i[0] < s.length() && Character.isDigit(s.charAt(i[0]))) {
num = num * 10 + (s.charAt(i[0]) - '0');
i[0]++;
}
return sign * num;
}
// Parses exactly one "( ... )" group and returns its value
static int parseGroup(String s, int[] i) {
skipSpaces(s, i);
// Current character must be '('
i[0]++;
skipSpaces(s, i);
int innerVal;
// If next part starts with '(' again, it is a nested expression
if (i[0] < s.length() && s.charAt(i[0]) == '(') {
innerVal = parseExpr(s, i);
}
else {
innerVal = parseNumber(s, i);
}
skipSpaces(s, i);
// Skip closing ')'
if (i[0] < s.length() && s.charAt(i[0]) == ')') {
i[0]++;
}
// Apply absolute value for this group
return Math.abs(innerVal);
}
static int parseExpr(String s, int[] i) {
ArrayList<Integer> vals = new ArrayList<>();
skipSpaces(s, i);
// Read consecutive groups until we hit ')' or reach the end
while (i[0] < s.length()) {
skipSpaces(s, i);
if (i[0] >= s.length() || s.charAt(i[0]) != '(')
break;
int v = parseGroup(s, i);
vals.add(v);
skipSpaces(s, i);
}
// Apply alternating sum: + - + - ...
int res = 0;
int sign = 1;
for (int v : vals) {
res += sign * v;
sign = -sign;
}
return res;
}
static int getValue(String s) {
int[] i = {0};
return parseExpr(s, i);
}
public static void main(String[] args) {
String s = "((-1)(3))";
int ans = getValue(s);
System.out.println(ans);
}
}
Python
# Skips all whitespace characters starting from index i
def skipSpaces(s, i):
while i[0] < len(s) and s[i[0]].isspace():
i[0] += 1
# Parses a signed integer starting at index i
def parseNumber(s, i):
skipSpaces(s, i)
sign = 1
# Handle optional sign
if i[0] < len(s) and (s[i[0]] == '+' or s[i[0]] == '-'):
if s[i[0]] == '-':
sign = -1
i[0] += 1
num = 0
while i[0] < len(s) and s[i[0]].isdigit():
num = num * 10 + int(s[i[0]])
i[0] += 1
return sign * num
# Parses exactly one "( ... )" group and returns its value
def parseGroup(s, i):
skipSpaces(s, i)
# Current character must be '('
i[0] += 1
skipSpaces(s, i)
# If next part starts with '(' again, it is a nested expression
if i[0] < len(s) and s[i[0]] == '(':
innerVal = parseExpr(s, i)
else:
innerVal = parseNumber(s, i)
skipSpaces(s, i)
# Skip closing ')'
if i[0] < len(s) and s[i[0]] == ')':
i[0] += 1
# Apply absolute value for this group
return abs(innerVal)
def parseExpr(s, i):
vals = []
skipSpaces(s, i)
# Read consecutive groups until we hit ')' or reach the end
while i[0] < len(s):
skipSpaces(s, i)
if i[0] >= len(s) or s[i[0]] != '(':
break
v = parseGroup(s, i)
vals.append(v)
skipSpaces(s, i)
# Apply alternating sum: + - + - ...
res = 0
sign = 1
for v in vals:
res += sign * v
sign = -sign
return res
def getValue(s):
i = [0]
return parseExpr(s, i)
if __name__ == "__main__":
s = "((-1)(3))"
print(getValue(s))
C#
using System;
using System.Collections.Generic;
class GFG {
// Skips all whitespace characters starting from index i
static void skipSpaces(string s, int[] i) {
while (i[0] < s.Length && Char.IsWhiteSpace(s[i[0]]))
i[0]++;
}
// Parses a signed integer starting at index i
static int parseNumber(string s, int[] i) {
skipSpaces(s, i);
int sign = 1;
// Handle optional sign
if (i[0] < s.Length && (s[i[0]] == '+' || s[i[0]] == '-')) {
if (s[i[0]] == '-') sign = -1;
i[0]++;
}
int num = 0;
while (i[0] < s.Length && Char.IsDigit(s[i[0]])) {
num = num * 10 + (s[i[0]] - '0');
i[0]++;
}
return sign * num;
}
// Parses exactly one "( ... )" group and returns its value
static int parseGroup(string s, int[] i) {
skipSpaces(s, i);
// Current character must be '('
i[0]++;
skipSpaces(s, i);
// If next part starts with '(' again, it is a nested expression
int innerVal = i[0] < s.Length && s[i[0]] == '(' ? parseExpr(s, i) : parseNumber(s, i);
skipSpaces(s, i);
// Skip closing ')'
if (i[0] < s.Length && s[i[0]] == ')')
i[0]++;
// Apply absolute value for this group
return Math.Abs(innerVal);
}
static int parseExpr(string s, int[] i) {
List<int> vals = new List<int>();
skipSpaces(s, i);
// Read consecutive groups until we hit ')' or reach the end
while (i[0] < s.Length) {
skipSpaces(s, i);
if (i[0] >= s.Length || s[i[0]] != '(')
break;
vals.Add(parseGroup(s, i));
skipSpaces(s, i);
}
// Apply alternating sum: + - + - ...
int res = 0;
int sign = 1;
foreach (int v in vals) {
res += sign * v;
sign = -sign;
}
return res;
}
static int getValue(string s) {
int[] i = {0};
return parseExpr(s, i);
}
static void Main() {
string s = "((-1)(3))";
int ans = getValue(s);
Console.WriteLine(ans);
}
}
JavaScript
// Skips all whitespace characters starting from index i
function skipSpaces(s, i) {
while (i.pos < s.length && /\s/.test(s[i.pos]))
i.pos++;
}
// Parses a signed integer starting at index i
function parseNumber(s, i) {
skipSpaces(s, i);
let sign = 1;
// Handle optional sign
if (i.pos < s.length && (s[i.pos] === '+' || s[i.pos] === '-')) {
if (s[i.pos] === '-') sign = -1;
i.pos++;
}
let num = 0;
while (i.pos < s.length && /[0-9]/.test(s[i.pos])) {
num = num * 10 + (s[i.pos] - '0');
i.pos++;
}
return sign * num;
}
// Parses exactly one "( ... )" group and returns its value
function parseGroup(s, i) {
skipSpaces(s, i);
// Current character must be '('
i.pos++;
skipSpaces(s, i);
// If next part starts with '(' again, it is a nested expression
let innerVal = i.pos < s.length && s[i.pos] === '(' ? parseExpr(s, i) : parseNumber(s, i);
skipSpaces(s, i);
// Skip closing ')'
if (i.pos < s.length && s[i.pos] === ')')
i.pos++;
// Apply absolute value for this group
return Math.abs(innerVal);
}
function parseExpr(s, i) {
let vals = [];
skipSpaces(s, i);
// Read consecutive groups until we hit ')' or reach the end
while (i.pos < s.length) {
skipSpaces(s, i);
if (i.pos >= s.length || s[i.pos] !== '(') break;
vals.push(parseGroup(s, i));
skipSpaces(s, i);
}
// Apply alternating sum: + - + - ...
let res = 0;
let sign = 1;
for (let v of vals) {
res += sign * v;
sign = -sign;
}
return res;
}
function getValue(s) {
let i = { pos: 0 };
return parseExpr(s, i);
}
//Driver
console.log(getValue("((-1)(3))"));
[Optimal Approach 2] Stack-Based Evaluation — O(n) Time and O(n) Space
In this approach, the string is evaluated iteratively using a stack. As the string is traversed, integers and opening brackets are pushed onto the stack. When a closing bracket is encountered, the value inside that parenthesis is resolved, its absolute value is computed, and the result is pushed back. After processing the full string, the stack contains the resolved values of consecutive groups, which are then combined using alternating addition and subtraction.
C++
#include <iostream>
#include <vector>
#include <stack>
#include <cctype>
#include <cmath>
using namespace std;
// Skip all whitespace characters starting from index i
void skipSpaces(const string &s, int &i) {
while (i < (int)s.size() && isspace(s[i]))
i++;
}
// Parse a signed integer starting at index i
int parseNumber(const string &s, int &i) {
skipSpaces(s, i);
int sign = 1;
// Handle optional sign (+ or -)
if (i < (int)s.size() && (s[i] == '+' || s[i] == '-')) {
if (s[i] == '-') sign = -1;
i++;
}
int num = 0;
while (i < (int)s.size() && isdigit(s[i])) {
num = num * 10 + (s[i] - '0');
i++;
}
return sign * num;
}
// Stack-based evaluation of the given parenthesis string
int getValue(string s) {
int n = (int)s.size();
int i = 0;
// Each element in the stack represents one "level" (between a pair of parentheses)
// and stores all values (numbers or inner group results) at that level.
stack<vector<int>> st;
st.push(vector<int>());
while (i < n) {
skipSpaces(s, i);
if (i >= n) break;
if (s[i] == '(') {
st.push(vector<int>());
i++;
}
else if (s[i] == ')') {
vector<int> top = st.top();
st.pop();
// First, compute alternating sum of values at this level: + - + - ...
int inner = 0;
int sign = 1;
for (int v : top) {
inner += sign * v;
sign = -sign;
}
// Apply absolute value for this completed "( ... )" group
int groupVal = abs(inner);
// Add the group result to the parent level
st.top().push_back(groupVal);
i++;
}
else {
// If it's not '(' or ')', it must be the start of a number
int num = parseNumber(s, i);
st.top().push_back(num);
}
}
// Finally, evaluate the root level with alternating + and -
vector<int> root = st.top();
int res = 0;
int sign = 1;
for (int v : root) {
res += sign * v;
sign = -sign;
}
return res;
}
int main() {
string s = "((-1)(3))";
int ans = getValue(s);
cout << ans << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.Stack;
class GFG {
// Skip all whitespace characters starting from index i
static void skipSpaces(String s, int[] i) {
while (i[0] < s.length() && Character.isWhitespace(s.charAt(i[0])))
i[0]++;
}
// Parse a signed integer starting at index i
static int parseNumber(String s, int[] i) {
skipSpaces(s, i);
int sign = 1;
// Handle optional sign (+ or -)
if (i[0] < s.length() && (s.charAt(i[0]) == '+' || s.charAt(i[0]) == '-')) {
if (s.charAt(i[0]) == '-') sign = -1;
i[0]++;
}
int num = 0;
while (i[0] < s.length() && Character.isDigit(s.charAt(i[0]))) {
num = num * 10 + (s.charAt(i[0]) - '0');
i[0]++;
}
return sign * num;
}
// Stack-based evaluation of the given parenthesis string
static int getValue(String s) {
int n = s.length();
int[] i = {0};
// Each element in the stack represents one "level"
Stack<ArrayList<Integer>> st = new Stack<>();
st.push(new ArrayList<>());
while (i[0] < n) {
skipSpaces(s, i);
if (i[0] >= n) break;
if (s.charAt(i[0]) == '(') {
st.push(new ArrayList<>());
i[0]++;
}
else if (s.charAt(i[0]) == ')') {
ArrayList<Integer> top = st.pop();
// First, compute alternating sum of values at this level: + - + - ...
int inner = 0;
int sign = 1;
for (int v : top) {
inner += sign * v;
sign = -sign;
}
// Apply absolute value for this completed "( ... )" group
int groupVal = Math.abs(inner);
// Add the group result to the parent level
st.peek().add(groupVal);
i[0]++;
}
else {
int num = parseNumber(s, i);
st.peek().add(num);
}
}
// Finally, evaluate the root level with alternating + and -
ArrayList<Integer> root = st.peek();
int res = 0;
int sign = 1;
for (int v : root) {
res += sign * v;
sign = -sign;
}
return res;
}
public static void main(String[] args) {
String s = "((-1)(3))";
int ans = getValue(s);
System.out.println(ans);
}
}
Python
# Skip all whitespace characters starting from index i
def skipSpaces(s, i):
while i[0] < len(s) and s[i[0]].isspace():
i[0] += 1
# Parse a signed integer starting at index i
def parseNumber(s, i):
skipSpaces(s, i)
sign = 1
# Handle optional sign (+ or -)
if i[0] < len(s) and (s[i[0]] == '+' or s[i[0]] == '-'):
if s[i[0]] == '-':
sign = -1
i[0] += 1
num = 0
while i[0] < len(s) and s[i[0]].isdigit():
num = num * 10 + int(s[i[0]])
i[0] += 1
return sign * num
# Stack-based evaluation of the given parenthesis string
def getValue(s):
n = len(s)
i = [0]
# Each element in the stack represents one "level"
# and stores all values (numbers or inner group results) at that level.
st = [[]]
while i[0] < n:
skipSpaces(s, i)
if i[0] >= n:
break
if s[i[0]] == '(':
st.append([])
i[0] += 1
elif s[i[0]] == ')':
top = st.pop()
# First, compute alternating sum of values at this level: + - + - ...
inner = 0
sign = 1
for v in top:
inner += sign * v
sign = -sign
# Apply absolute value for this completed "( ... )" group
groupVal = abs(inner)
# Add the group result to the parent level
st[-1].append(groupVal)
i[0] += 1
else:
# If it's not '(' or ')', it must be the start of a number
num = parseNumber(s, i)
st[-1].append(num)
# Finally, evaluate the root level with alternating + and -
root = st[-1]
res = 0
sign = 1
for v in root:
res += sign * v
sign = -sign
return res
if __name__ == "__main__":
s = "((-1)(3))"
ans = getValue(s)
print(ans)
C#
using System;
using System.Collections.Generic;
class GFG {
// Skip all whitespace characters starting from index i
static void skipSpaces(string s, int[] i) {
while (i[0] < s.Length && Char.IsWhiteSpace(s[i[0]]))
i[0]++;
}
// Parse a signed integer starting at index i
static int parseNumber(string s, int[] i) {
skipSpaces(s, i);
int sign = 1;
// Handle optional sign (+ or -)
if (i[0] < s.Length && (s[i[0]] == '+' || s[i[0]] == '-')) {
if (s[i[0]] == '-') sign = -1;
i[0]++;
}
int num = 0;
while (i[0] < s.Length && Char.IsDigit(s[i[0]])) {
num = num * 10 + (s[i[0]] - '0');
i[0]++;
}
return sign * num;
}
// Stack-based evaluation of the given parenthesis string
static int getValue(string s) {
int n = s.Length;
int[] i = {0};
// Each element in the stack represents one "level"
// and stores all values (numbers or inner group results) at that level.
Stack<List<int>> st = new Stack<List<int>>();
st.Push(new List<int>());
while (i[0] < n) {
skipSpaces(s, i);
if (i[0] >= n) break;
if (s[i[0]] == '(') {
st.Push(new List<int>());
i[0]++;
}
else if (s[i[0]] == ')') {
List<int> top = st.Pop();
// First, compute alternating sum of values at this level: + - + - ...
int inner = 0;
int sign = 1;
foreach (int v in top) {
inner += sign * v;
sign = -sign;
}
// Apply absolute value for this completed "( ... )" group
int groupVal = Math.Abs(inner);
// Add the group result to the parent level
st.Peek().Add(groupVal);
i[0]++;
}
else {
int num = parseNumber(s, i);
st.Peek().Add(num);
}
}
// Finally, evaluate the root level with alternating + and -
List<int> root = st.Peek();
int res = 0;
int signRoot = 1;
foreach (int v in root) {
res += signRoot * v;
signRoot = -signRoot;
}
return res;
}
static void Main() {
string s = "((-1)(3))";
int ans = getValue(s);
Console.WriteLine(ans);
}
}
JavaScript
// Skip all whitespace characters starting from index i
function skipSpaces(s, i) {
while (i.pos < s.length && /\s/.test(s[i.pos])) i.pos++;
}
// Parse a signed integer starting at index i
function parseNumber(s, i) {
skipSpaces(s, i);
let sign = 1;
// Handle optional sign (+ or -)
if (i.pos < s.length && (s[i.pos] === '+' || s[i.pos] === '-')) {
if (s[i.pos] === '-') sign = -1;
i.pos++;
}
let num = 0;
while (i.pos < s.length && /\d/.test(s[i.pos])) {
num = num * 10 + (s[i.pos] - '0');
i.pos++;
}
return sign * num;
}
// Stack-based evaluation of the given parenthesis string
function getValue(s) {
let n = s.length;
let i = { pos: 0 };
// Each element in the stack represents one "level"
// and stores all values (numbers or inner group results) at that level.
let st = [[]];
while (i.pos < n) {
skipSpaces(s, i);
if (i.pos >= n) break;
if (s[i.pos] === '(') {
st.push([]);
i.pos++;
}
else if (s[i.pos] === ')') {
let top = st.pop();
// First, compute alternating sum of values at this level: + - + - ...
let inner = 0;
let sign = 1;
for (let v of top) {
inner += sign * v;
sign = -sign;
}
// Apply absolute value for this completed "( ... )" group
let groupVal = Math.abs(inner);
// Add the group result to the parent level
st[st.length - 1].push(groupVal);
i.pos++;
}
else {
let num = parseNumber(s, i);
st[st.length - 1].push(num);
}
}
// Finally, evaluate the root level with alternating + and -
let root = st[st.length - 1];
let res = 0;
let signRoot = 1;
for (let v of root) {
res += signRoot * v;
signRoot = -signRoot;
}
return res;
}
// Driver
let s = "((-1)(3))";
let ans = getValue(s);
console.log(ans);
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem