Check if two expressions with brackets are same - GeeksforGeeks

30 Aug, 2021
Given two expressions in the form of strings. The task is to compare them and check if they are similar. Expressions consist of lowercase alphabets, ‘+’, ‘-‘ and ‘( )’.Examples:  
Input  : exp1 = "-(a+b+c)"
         exp2 = "-a-b-c"
Output : Yes

Input  : exp1 = "-(c+b+a)"
         exp2 = "-c-b-a"
Output : Yes

Input  : exp1 = "a-b-(c-d)"
         exp2 = "a-b-c-d"
Output : No
It may be assumed that there are at most 26 operands from ‘a’ to ‘z’ and every operand appears only once. 
A simple idea behind is to keep a record of the Global and Local Sign(+/-) through the expression. The Global Sign here means the multiplicative sign at each operand. The resultant sign for an operand is local sign multiplied by the global sign at that operand.For example, the expression a+b-(c-d) is evaluated as (+)+a(+)+b(-)+c(-)-d => a + b – c + d. The global sign (represented inside bracket) is multiplied to the local sign for each operand.In the given solution, stack is used to keep record of the global signs. A count vector records the counts of the operands(lowercase Latin letters here). Two expressions are evaluated in opposite manners and finally, it is checked if the all entries in the count vector are zeros.  
C++
Java
Python3
C#
Javascript
// CPP program to check if two expressions// evaluate to same.#include <bits/stdc++.h>using namespace std; const int MAX_CHAR = 26; // Return local sign of the operand. For example,// in the expr a-b-(c), local signs of the operands// are +a, -b, +cbool adjSign(string s, int i){    if (i == 0)        return true;    if (s[i - 1] == '-')        return false;    return true;}; // Evaluate expressions into the count vector of// the 26 alphabets.If add is true, then add count// to the count vector of the alphabets, else remove// count from the count vector.void eval(string s, vector<int>& v, bool add){    // stack stores the global sign    // for operands.    stack<bool> stk;    stk.push(true);     // + means true    // global sign is positive initially     int i = 0;    while (s[i] != '\0') {        if (s[i] == '+' || s[i] == '-') {            i++;            continue;        }        if (s[i] == '(') {             // global sign for the bracket is            // pushed to the stack            if (adjSign(s, i))                stk.push(stk.top());            else                stk.push(!stk.top());        }         // global sign is popped out which        // was pushed in for the last bracket        else if (s[i] == ')')            stk.pop();                 else {             // global sign is positive (we use different            // values in two calls of functions so that            // we finally check if all vector elements            // are 0.            if (stk.top())                                v[s[i] - 'a'] += (adjSign(s, i) ? add ? 1 : -1 :                                                  add ? -1 : 1);             // global sign is negative here            else                                v[s[i] - 'a'] += (adjSign(s, i) ? add ? -1 : 1 :                                                  add ? 1 : -1);        }        i++;    }}; // Returns true if expr1 and expr2 represent// same expressionsbool areSame(string expr1, string expr2){    // Create a vector for all operands and    // initialize the vector as 0.    vector<int> v(MAX_CHAR, 0);     // Put signs of all operands in expr1    eval(expr1, v, true);     // Subtract signs of operands in expr2    eval(expr2, v, false);     // If expressions are same, vector must    // be 0.    for (int i = 0; i < MAX_CHAR; i++)        if (v[i] != 0)            return false;     return true;} // Driver codeint main(){    string expr1 = "-(a+b+c)", expr2 = "-a-b-c";    if (areSame(expr1, expr2))        cout << "Yes\n";    else        cout << "No\n";    return 0;}
// Java program to check if two expressions// evaluate to same.import java.io.*;import java.util.*; class GFG{     static final int MAX_CHAR = 26;     // Return local sign of the operand. For example,    // in the expr a-b-(c), local signs of the operands    // are +a, -b, +c    static boolean adjSign(String s, int i)    {        if (i == 0)            return true;        if (s.charAt(i - 1) == '-')            return false;        return true;    };     // Evaluate expressions into the count vector of    // the 26 alphabets.If add is true, then add count    // to the count vector of the alphabets, else remove    // count from the count vector.    static void eval(String s, int[] v, boolean add)    {         // stack stores the global sign        // for operands.        Stack<Boolean> stk = new Stack<>();        stk.push(true);         // + means true        // global sign is positive initially         int i = 0;        while (i < s.length())        {            if (s.charAt(i) == '+' || s.charAt(i) == '-')            {                i++;                continue;            }            if (s.charAt(i) == '(')            {                 // global sign for the bracket is                // pushed to the stack                if (adjSign(s, i))                    stk.push(stk.peek());                else                    stk.push(!stk.peek());            }             // global sign is popped out which            // was pushed in for the last bracket            else if (s.charAt(i) == ')')                stk.pop();             else            {                 // global sign is positive (we use different                // values in two calls of functions so that                // we finally check if all vector elements                // are 0.                if (stk.peek())                    v[s.charAt(i) - 'a'] += (adjSign(s, i) ?                               add ? 1 : -1 : add ? -1 : 1);                 // global sign is negative here                else                    v[s.charAt(i) - 'a'] += (adjSign(s, i) ?                                add ? -1 : 1 : add ? 1 : -1);            }            i++;        }    };     // Returns true if expr1 and expr2 represent    // same expressions    static boolean areSame(String expr1, String expr2)    {         // Create a vector for all operands and        // initialize the vector as 0.        int[] v = new int[MAX_CHAR];         // Put signs of all operands in expr1        eval(expr1, v, true);         // Subtract signs of operands in expr2        eval(expr2, v, false);         // If expressions are same, vector must        // be 0.        for (int i = 0; i < MAX_CHAR; i++)            if (v[i] != 0)                return false;         return true;    }     // Driver Code    public static void main(String[] args)    {         String expr1 = "-(a+b+c)", expr2 = "-a-b-c";        if (areSame(expr1, expr2))            System.out.println("Yes");        else            System.out.println("No");    }} // This code is contributed by// sanjeev2552
# Python3 program to check if two expressions# evaluate to same.MAX_CHAR = 26; # Return local sign of the operand. For example,# in the expr a-b-(c), local signs of the operands# are +a, -b, +cdef adjSign(s, i):  if (i == 0):    return True;  if (s[i - 1] == '-'):    return False;  return True; # Evaluate expressions into the count vector of# the 26 alphabets.If add is True, then add count# to the count vector of the alphabets, else remove# count from the count vector.def eval(s, v, add):     # stack stores the global sign  # for operands.  stk = []  stk.append(True);     # + means True  # global sign is positive initially  i = 0;   while (i < len(s)):     if (s[i] == '+' or s[i] == '-'):      i += 1      continue;         if (s[i] == '('):             # global sign for the bracket is      # pushed to the stack      if (adjSign(s, i)):        stk.append(stk[-1]);      else:        stk.append(not stk[-1]);         # global sign is popped out which    # was pushed in for the last bracket    elif (s[i] == ')'):      stk.pop();    else:             # global sign is positive (we use different      # values in two calls of functions so that      # we finally check if all vector elements      # are 0.      if (stk[-1]):        v[ord(s[i]) - ord('a')] += (1 if add else -1) if adjSign(s, i) else (-1 if add else 1)             # global sign is negative here      else:        v[ord(s[i]) - ord('a')] += (-1 if add else 1) if adjSign(s, i) else (1 if add else -1)         i += 1   # Returns True if expr1 and expr2 represent# same expressionsdef areSame(expr1, expr2):     # Create a vector for all operands and  # initialize the vector as 0.  v = [0 for i in range(MAX_CHAR)];     # Put signs of all operands in expr1  eval(expr1, v, True);     # Subtract signs of operands in expr2  eval(expr2, v, False);     # If expressions are same, vector must  # be 0.  for i in range(MAX_CHAR):    if (v[i] != 0):      return False;  return True; # Driver Codeif __name__=='__main__':  expr1 = "-(a+b+c)"  expr2 = "-a-b-c";  if (areSame(expr1, expr2)):    print("Yes");  else:    print("No");     # This code is contributed by rutvik_56.
// C# program to check if two expressions// evaluate to same.using System;using System.Collections.Generic;public class GFG{   static readonly int MAX_CHAR = 26;   // Return local sign of the operand. For example,  // in the expr a-b-(c), local signs of the operands  // are +a, -b, +c  static bool adjSign(String s, int i)  {    if (i == 0)      return true;    if (s[i-1] == '-')      return false;    return true;  }   // Evaluate expressions into the count vector of  // the 26 alphabets.If add is true, then add count  // to the count vector of the alphabets, else remove  // count from the count vector.  static void eval(String s, int[] v, bool add)  {     // stack stores the global sign    // for operands.    Stack<Boolean> stk = new Stack<Boolean>();    stk.Push(true);     // + means true    // global sign is positive initially    int i = 0;    while (i < s.Length)    {      if (s[i] == '+' || s[i] == '-')      {        i++;        continue;      }      if (s[i] == '(')      {         // global sign for the bracket is        // pushed to the stack        if (adjSign(s, i))          stk.Push(stk.Peek());        else          stk.Push(!stk.Peek());      }       // global sign is popped out which      // was pushed in for the last bracket      else if (s[i] == ')')        stk.Pop();       else      {         // global sign is positive (we use different        // values in two calls of functions so that        // we finally check if all vector elements        // are 0.        if (stk.Peek())          v[s[i] - 'a'] += (adjSign(s, i) ?                            add ? 1 : -1 : add ? -1 : 1);         // global sign is negative here        else          v[s[i] - 'a'] += (adjSign(s, i) ?                            add ? -1 : 1 : add ? 1 : -1);      }      i++;    }  }   // Returns true if expr1 and expr2 represent  // same expressions  static bool areSame(String expr1, String expr2)  {     // Create a vector for all operands and    // initialize the vector as 0.    int[] v = new int[MAX_CHAR];     // Put signs of all operands in expr1    eval(expr1, v, true);     // Subtract signs of operands in expr2    eval(expr2, v, false);     // If expressions are same, vector must    // be 0.    for (int i = 0; i < MAX_CHAR; i++)      if (v[i] != 0)        return false;     return true;  }   // Driver Code  public static void Main(String[] args)  {     String expr1 = "-(a+b+c)", expr2 = "-a-b-c";    if (areSame(expr1, expr2))      Console.WriteLine("Yes");    else      Console.WriteLine("No");  }} // This code is contributed by Rajput-Ji
<script>    // Javascript program to check if two expressions    // evaluate to same.         let MAX_CHAR = 26;      // Return local sign of the operand. For example,    // in the expr a-b-(c), local signs of the operands    // are +a, -b, +c    function adjSign(s, i)    {        if (i == 0)            return true;        if (s[i - 1] == '-')            return false;        return true;    }      // Evaluate expressions into the count vector of    // the 26 alphabets.If add is true, then add count    // to the count vector of the alphabets, else remove    // count from the count vector.    function eval(s, v, add)    {          // stack stores the global sign        // for operands.        let stk = [];        stk.push(true);          // + means true        // global sign is positive initially          let i = 0;        while (i < s.length)        {            if (s[i] == '+' || s[i] == '-')            {                i++;                continue;            }            if (s[i] == '(')            {                  // global sign for the bracket is                // pushed to the stack                if (adjSign(s, i))                    stk.push(stk[stk.length - 1]);                else                    stk.push(!stk[stk.length - 1]);            }              // global sign is popped out which            // was pushed in for the last bracket            else if (s[i] == ')')                stk.pop();              else            {                  // global sign is positive (we use different                // values in two calls of functions so that                // we finally check if all vector elements                // are 0.                if (stk[stk.length - 1])                    v[s[i] - 'a'] += (adjSign(s, i) ?                               add ? 1 : -1 : add ? -1 : 1);                  // global sign is negative here                else                    v[s[i] - 'a'] += (adjSign(s, i) ?                                add ? -1 : 1 : add ? 1 : -1);            }            i++;        }    };      // Returns true if expr1 and expr2 represent    // same expressions    function areSame(expr1, expr2)    {          // Create a vector for all operands and        // initialize the vector as 0.        let v = new Array(MAX_CHAR);        v.fill(0);          // Put signs of all operands in expr1        eval(expr1, v, true);          // Subtract signs of operands in expr2        eval(expr2, v, false);          // If expressions are same, vector must        // be 0.        for (let i = 0; i < MAX_CHAR; i++)            if (v[i] != 0)                return false;          return true;    }         let expr1 = "-(a+b+c)", expr2 = "-a-b-c";    if (areSame(expr1, expr2))      document.write("YES");    else      document.write("NO");         // This code is contributed by suresh07.</script>
Output:  
YES
This article is contributed by Amol Mejari. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
sanjeev2552
Rajput-Ji
rutvik_56
suresh07
Amazon
cpp-vector
Stack
Strings
Amazon
Strings
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Program for Tower of Hanoi
Implement a stack using singly linked list
Implement Stack using Queues
Iterative Depth First Traversal of Graph
Merge Overlapping Intervals
Reverse a string in Java
Write a program to reverse an array or string
Longest Common Subsequence | DP-4
Write a program to print all permutations of a given string
C++ Data Types