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.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
bool adjSign(string s, int i)
{
if (i == 0)
return true ;
if (s[i - 1] == '-' )
return false ;
return true ;
};
void eval(string s, vector< int >& v, bool add)
{
stack< bool > stk;
stk.push( true );
int i = 0;
while (s[i] != '\0' ) {
if (s[i] == '+' || s[i] == '-' ) {
i++;
continue ;
}
if (s[i] == '(' ) {
if (adjSign(s, i))
stk.push(stk.top());
else
stk.push(!stk.top());
}
else if (s[i] == ')' )
stk.pop();
else {
if (stk.top())
v[s[i] - 'a' ] += (adjSign(s, i) ? add ? 1 : -1 :
add ? -1 : 1);
else
v[s[i] - 'a' ] += (adjSign(s, i) ? add ? -1 : 1 :
add ? 1 : -1);
}
i++;
}
};
bool areSame(string expr1, string expr2)
{
vector< int > v(MAX_CHAR, 0);
eval(expr1, v, true );
eval(expr2, v, false );
for ( int i = 0; i < MAX_CHAR; i++)
if (v[i] != 0)
return false ;
return true ;
}
int main()
{
string expr1 = "-(a+b+c)" , expr2 = "-a-b-c" ;
if (areSame(expr1, expr2))
cout << "Yes\n" ;
else
cout << "No\n" ;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static final int MAX_CHAR = 26 ;
static boolean adjSign(String s, int i)
{
if (i == 0 )
return true ;
if (s.charAt(i - 1 ) == '-' )
return false ;
return true ;
};
static void eval(String s, int [] v, boolean add)
{
Stack<Boolean> stk = new Stack<>();
stk.push( true );
int i = 0 ;
while (i < s.length())
{
if (s.charAt(i) == '+' || s.charAt(i) == '-' )
{
i++;
continue ;
}
if (s.charAt(i) == '(' )
{
if (adjSign(s, i))
stk.push(stk.peek());
else
stk.push(!stk.peek());
}
else if (s.charAt(i) == ')' )
stk.pop();
else
{
if (stk.peek())
v[s.charAt(i) - 'a' ] += (adjSign(s, i) ?
add ? 1 : - 1 : add ? - 1 : 1 );
else
v[s.charAt(i) - 'a' ] += (adjSign(s, i) ?
add ? - 1 : 1 : add ? 1 : - 1 );
}
i++;
}
};
static boolean areSame(String expr1, String expr2)
{
int [] v = new int [MAX_CHAR];
eval(expr1, v, true );
eval(expr2, v, false );
for ( int i = 0 ; i < MAX_CHAR; i++)
if (v[i] != 0 )
return false ;
return true ;
}
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" );
}
}
|
Python3
MAX_CHAR = 26 ;
def adjSign(s, i):
if (i = = 0 ):
return True ;
if (s[i - 1 ] = = '-' ):
return False ;
return True ;
def eval (s, v, add):
stk = []
stk.append( True );
i = 0 ;
while (i < len (s)):
if (s[i] = = '+' or s[i] = = '-' ):
i + = 1
continue ;
if (s[i] = = '(' ):
if (adjSign(s, i)):
stk.append(stk[ - 1 ]);
else :
stk.append( not stk[ - 1 ]);
elif (s[i] = = ')' ):
stk.pop();
else :
if (stk[ - 1 ]):
v[ ord (s[i]) - ord ( 'a' )] + = ( 1 if add else - 1 ) if adjSign(s, i) else ( - 1 if add else 1 )
else :
v[ ord (s[i]) - ord ( 'a' )] + = ( - 1 if add else 1 ) if adjSign(s, i) else ( 1 if add else - 1 )
i + = 1
def areSame(expr1, expr2):
v = [ 0 for i in range (MAX_CHAR)];
eval (expr1, v, True );
eval (expr2, v, False );
for i in range (MAX_CHAR):
if (v[i] ! = 0 ):
return False ;
return True ;
if __name__ = = '__main__' :
expr1 = "-(a+b+c)"
expr2 = "-a-b-c" ;
if (areSame(expr1, expr2)):
print ( "Yes" );
else :
print ( "No" );
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static readonly int MAX_CHAR = 26;
static bool adjSign(String s, int i)
{
if (i == 0)
return true ;
if (s[i-1] == '-' )
return false ;
return true ;
}
static void eval(String s, int [] v, bool add)
{
Stack<Boolean> stk = new Stack<Boolean>();
stk.Push( true );
int i = 0;
while (i < s.Length)
{
if (s[i] == '+' || s[i] == '-' )
{
i++;
continue ;
}
if (s[i] == '(' )
{
if (adjSign(s, i))
stk.Push(stk.Peek());
else
stk.Push(!stk.Peek());
}
else if (s[i] == ')' )
stk.Pop();
else
{
if (stk.Peek())
v[s[i] - 'a' ] += (adjSign(s, i) ?
add ? 1 : -1 : add ? -1 : 1);
else
v[s[i] - 'a' ] += (adjSign(s, i) ?
add ? -1 : 1 : add ? 1 : -1);
}
i++;
}
}
static bool areSame(String expr1, String expr2)
{
int [] v = new int [MAX_CHAR];
eval(expr1, v, true );
eval(expr2, v, false );
for ( int i = 0; i < MAX_CHAR; i++)
if (v[i] != 0)
return false ;
return true ;
}
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" );
}
}
|
Javascript
<script>
let MAX_CHAR = 26;
function adjSign(s, i)
{
if (i == 0)
return true ;
if (s[i - 1] == '-' )
return false ;
return true ;
}
function eval(s, v, add)
{
let stk = [];
stk.push( true );
let i = 0;
while (i < s.length)
{
if (s[i] == '+' || s[i] == '-' )
{
i++;
continue ;
}
if (s[i] == '(' )
{
if (adjSign(s, i))
stk.push(stk[stk.length - 1]);
else
stk.push(!stk[stk.length - 1]);
}
else if (s[i] == ')' )
stk.pop();
else
{
if (stk[stk.length - 1])
v[s[i] - 'a' ] += (adjSign(s, i) ?
add ? 1 : -1 : add ? -1 : 1);
else
v[s[i] - 'a' ] += (adjSign(s, i) ?
add ? -1 : 1 : add ? 1 : -1);
}
i++;
}
};
function areSame(expr1, expr2)
{
let v = new Array(MAX_CHAR);
v.fill(0);
eval(expr1, v, true );
eval(expr2, v, false );
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" );
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
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.