📌  相关文章
📜  检查是否可以使用给定字符串的串联形成正则括号序列

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

检查是否可以使用给定字符串的串联形成正则括号序列

给定一个由N个字符串组成的数组arr[] ,其中每个字符串由'('')'组成,任务是检查一个正则括号序列 可以由给定字符串的串联形成,也可以不形成。如果发现是真的,则打印Yes 。否则打印No

例子:

方法:给定的问题可以借助基于以下观察的贪婪方法来解决:

  • 如果字符串包含一对连续的字母'(' 和 ')' ,则删除这两个字母不会影响结果。
  • 通过重复此操作,每个S[i]变成一个(可能为空)字符串,由 0 次或多次重复的 ')' 组成,然后是 0 次或多次重复的 '('
  • 那么每个字符串都可以用两个变量A[i] = ')' 的数量和 B[i] = '(' 的数量来表示
  • 维护一个对向量v[][]来存储这些值。
  • 现在,将两个字符串分成两个单独的向量pos[]neg[]
  • pos[]将存储总和为的字符串,而neg[]将存储总和为的字符串。
  • 现在最佳方法是先连接正字符串,然后按递增顺序连接负字符串。

请按照以下步骤解决问题:

  • 维护一个将存储值{sum, minimum prefix}的对向量v[][] ,其中总和由'('+1')'-1计算,最小前缀是最大连续') '在字符串中。
  • 迭代范围[0. N)使用变量i并执行以下步骤:
    • 将 2 个变量sumpre初始化为0以存储给定字符串的 sum 和最小前缀。
    • 迭代字符串的每个字符的范围[0, M) ,如果当前字符是'('则将sum增加1否则将其减少1并将pre 的值设置为 presum的最小值步。
    • v[ I ]的值设置为{ sum, pre }。
  • 迭代范围[0. N)对于v[]中的元素和每一对,如果总和为正,则将值{-min_prefix, sum}存储在 pos[] 向量中,否则将{sum – min_prefix, -sum} 存储在 neg[] 向量中。
  • 按升序对这些向量进行排序。
  • 将变量open初始化为0
  • 迭代范围[0. size)其中size是使用迭代器变量p的向量pos[]的大小,如果open – p.first大于等于0 ,则将p.second添加到变量open中。否则,打印No并返回。
  • 将变量负数初始化为0
  • 迭代范围[0. size)其中size是使用迭代器变量p的向量neg[]的大小,如果为负 - p.first大于等于0 ,则将p.second添加到变量negative 。否则,打印No并返回。
  • 如果open的值不等于负数,则打印No 。否则,打印Yes

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check possible RBS from
// the given strings
int checkRBS(vector S)
{
    int N = S.size();
 
    // Stores the values {sum, min_prefix}
    vector > v(N);
 
    // Iterate over the range
    for (int i = 0; i < N; ++i) {
        string s = S[i];
 
        // Stores the total sum
        int sum = 0;
 
        // Stores the minimum prefix
        int pre = 0;
        for (char c : s) {
            if (c == '(') {
                ++sum;
            }
            else {
                --sum;
            }
 
            // Check for minimum prefix
            pre = min(sum, pre);
        }
 
        // Store these values in vector
        v[i] = { sum, pre };
    }
 
    // Make two pair vectors pos and neg
    vector > pos;
    vector > neg;
 
    // Store values according to the
    // mentioned approach
    for (int i = 0; i < N; ++i) {
        if (v[i].first >= 0) {
            pos.push_back(
                { -v[i].second, v[i].first });
        }
        else {
            neg.push_back(
                { v[i].first - v[i].second,
                  -v[i].first });
        }
    }
 
    // Sort the positive vector
    sort(pos.begin(), pos.end());
 
    // Stores the extra count of
    // open brackets
    int open = 0;
    for (auto p : pos) {
        if (open - p.first >= 0) {
            open += p.second;
        }
 
        // No valid bracket sequence
        // can be formed
        else {
            cout << "No"
                 << "\n";
            return 0;
        }
    }
 
    // Sort the negative vector
    sort(neg.begin(), neg.end());
 
    // Stores the count of the
    // negative elements
    int negative = 0;
    for (auto p : neg) {
 
        if (negative - p.first >= 0) {
            negative += p.second;
        }
 
        // No valid bracket sequence
        // can be formed
        else {
            cout << "No\n";
            return 0;
        }
    }
 
    // Check if open is equal to negative
    if (open != negative) {
        cout << "No\n";
        return 0;
    }
    cout << "Yes\n";
    return 0;
}
 
// Driver Code
int main()
{
    vector arr = { ")", "()(" };
    checkRBS(arr);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
    static class pair
    {
        int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
// Function to check possible RBS from
// the given Strings
static int checkRBS(String[] S)
{
    int N = S.length;
 
    // Stores the values {sum, min_prefix}
    pair []v = new pair[N];
 
    // Iterate over the range
    for (int i = 0; i < N; ++i) {
        String s = S[i];
 
        // Stores the total sum
        int sum = 0;
 
        // Stores the minimum prefix
        int pre = 0;
        for (char c : s.toCharArray()) {
            if (c == '(') {
                ++sum;
            }
            else {
                --sum;
            }
 
            // Check for minimum prefix
            pre = Math.min(sum, pre);
        }
 
        // Store these values in vector
        v[i] = new pair( sum, pre );
    }
 
    // Make two pair vectors pos and neg
    Vector pos = new Vector();
    Vector neg = new Vector();
 
    // Store values according to the
    // mentioned approach
    for (int i = 0; i < N; ++i) {
        if (v[i].first >= 0) {
            pos.add(
                new pair( -v[i].second, v[i].first ));
        }
        else {
            neg.add(
                    new pair( v[i].first - v[i].second,
                  -v[i].first ));
        }
    }
 
    // Sort the positive vector
    Collections.sort(pos,(a,b)->a.first-b.first);
 
    // Stores the extra count of
    // open brackets
    int open = 0;
    for (pair p : pos) {
        if (open - p.first >= 0) {
            open += p.second;
        }
 
        // No valid bracket sequence
        // can be formed
        else {
            System.out.print("No"
                + "\n");
            return 0;
        }
    }
 
    // Sort the negative vector
    Collections.sort(neg,(a,b)->a.first-b.first);
 
    // Stores the count of the
    // negative elements
    int negative = 0;
    for (pair p : neg) {
 
        if (negative - p.first >= 0) {
            negative += p.second;
        }
 
        // No valid bracket sequence
        // can be formed
        else {
            System.out.print("No\n");
            return 0;
        }
    }
 
    // Check if open is equal to negative
    if (open != negative) {
        System.out.print("No\n");
        return 0;
     
    }
    System.out.print("Yes\n");
    return 0;
}
 
// Driver Code
public static void main(String[] args)
{
    String []arr = { ")", "()(" };
    checkRBS(arr);
 
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python 3 program for the above approach
 
# Function to check possible RBS from
# the given strings
def checkRBS(S):
 
    N = len(S)
 
    # Stores the values {sum, min_prefix}
    v = [0]*(N)
 
    # Iterate over the range
    for i in range(N):
        s = S[i]
 
        # Stores the total sum
        sum = 0
 
        # Stores the minimum prefix
        pre = 0
        for c in s:
            if (c == '('):
                sum += 1
 
            else:
                sum -= 1
 
            # Check for minimum prefix
            pre = min(sum, pre)
 
        # Store these values in vector
        v[i] = [sum, pre]
 
    pos = []
    neg = []
 
    # Store values according to the
    # mentioned approach
    for i in range(N):
        if (v[i][0] >= 0):
            pos.append(
                [-v[i][1], v[i][0]])
 
        else:
            neg.append(
                [v[i][0] - v[i][1],
                 -v[i][0]])
 
    # Sort the positive vector
    pos.sort()
 
    # Stores the extra count of
    # open brackets
    open = 0
    for p in pos:
        if (open - p[0] >= 0):
            open += p[1]
 
        # No valid bracket sequence
        # can be formed
        else:
            print("No")
 
            return 0
 
    # Sort the negative vector
    neg.sort()
 
    # Stores the count of the
    # negative elements
    negative = 0
    for p in neg:
 
        if (negative - p[0] >= 0):
            negative += p[1]
 
        # No valid bracket sequence
        # can be formed
        else:
            print("No")
            return 0
 
    # Check if open is equal to negative
    if (open != negative):
        print("No")
        return 0
 
    print("Yes")
 
# Driver Code
if __name__ == "__main__":
 
    arr = [")", "()("]
    checkRBS(arr)
 
    # This code is contributed by ukasp.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG{
 class pair : IComparable
    {
        public int first,second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }
 
        public int CompareTo(pair p)
        {
            return this.first - p.first;
        }
    }
   
// Function to check possible RBS from
// the given Strings
static int checkRBS(String[] S)
{
    int N = S.Length;
 
    // Stores the values {sum, min_prefix}
    pair []v = new pair[N];
 
    // Iterate over the range
    for (int i = 0; i < N; ++i) {
        String s = S[i];
 
        // Stores the total sum
        int sum = 0;
 
        // Stores the minimum prefix
        int pre = 0;
        foreach (char c in s.ToCharArray()) {
            if (c == '(') {
                ++sum;
            }
            else {
                --sum;
            }
 
            // Check for minimum prefix
            pre = Math.Min(sum, pre);
        }
 
        // Store these values in vector
        v[i] = new pair( sum, pre );
    }
 
    // Make two pair vectors pos and neg
    List pos = new List();
    List neg = new List();
 
    // Store values according to the
    // mentioned approach
    for (int i = 0; i < N; ++i) {
        if (v[i].first >= 0) {
            pos.Add(
                new pair( -v[i].second, v[i].first ));
        }
        else {
            neg.Add(
                    new pair( v[i].first - v[i].second,
                  -v[i].first ));
        }
    }
 
    // Sort the positive vector
    pos.Sort();
 
    // Stores the extra count of
    // open brackets
    int open = 0;
    foreach (pair p in pos) {
        if (open - p.first >= 0) {
            open += p.second;
        }
 
        // No valid bracket sequence
        // can be formed
        else {
            Console.Write("No"
                + "\n");
            return 0;
        }
    }
 
    // Sort the negative vector
    neg.Sort();
 
    // Stores the count of the
    // negative elements
    int negative = 0;
    foreach (pair p in neg) {
 
        if (negative - p.first >= 0) {
            negative += p.second;
        }
 
        // No valid bracket sequence
        // can be formed
        else {
            Console.Write("No\n");
            return 0;
        }
    }
 
    // Check if open is equal to negative
    if (open != negative) {
        Console.Write("No\n");
        return 0;
     
    }
    Console.Write("Yes\n");
    return 0;
}
 
// Driver Code
public static void Main(String[] args)
{
    String []arr = { ")", "()(" };
    checkRBS(arr);
 
}
}
 
// This code is contributed by 29AjayKumar


Javascript


输出:
Yes

时间复杂度: O(N*M + N*log(N)),其中 M 是数组 arr[] 中字符串的最大长度。
辅助空间: O(N)