Open In App

Get Value from Parenthesis

Last Updated : 11 Dec, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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);

Output
2

[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))"));

Output
2

[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);

Output
2



Article Tags :

Explore