📌  相关文章
📜  检查两个带括号的表达式是否相同

📅  最后修改于: 2022-05-13 01:57:08.994000             🧑  作者: Mango

检查两个带括号的表达式是否相同

给定两个字符串形式的表达式。任务是比较它们并检查它们是否相似。表达式由小写字母、“+”、“-”和“()”组成。
例子:

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