检查两个带括号的表达式是否相同
给定两个字符串形式的表达式。任务是比较它们并检查它们是否相似。表达式由小写字母、“+”、“-”和“()”组成。
例子:
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
可以假设从“a”到“z”最多有26个操作数,每个操作数只出现一次。
背后的一个简单想法是通过表达式记录全局和局部符号(+/-) 。这里的全局符号表示每个操作数的乘法符号。操作数的结果符号是局部符号乘以该操作数的全局符号。
例如,表达式 a+b-(cd) 的计算结果为 (+)+a(+)+b(-)+c(-)-d => a + b – c + d。全局符号(在括号内表示)乘以每个操作数的局部符号。
在给定的解决方案中,堆栈用于记录全局符号。计数向量记录操作数的计数(此处为小写拉丁字母)。以相反的方式计算两个表达式,最后检查计数向量中的所有条目是否为零。
C++
// CPP program to check if two expressions
// evaluate to same.
#include
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, +c
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.
void eval(string s, vector& v, bool add)
{
// stack stores the global sign
// for operands.
stack 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 expressions
bool areSame(string expr1, string expr2)
{
// Create a vector for all operands and
// initialize the vector as 0.
vector 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 code
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
// 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 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
# 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, +c
def 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 expressions
def 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 Code
if __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#
// 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 stk = new Stack();
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
Javascript
输出:
YES