# Maximum Pairs of Bracket Sequences which can be concatenated to form a Regular Bracket Sequence

Regular Bracket Sequence means a string that contains the parentheses of both opening and closing types and results in properly closed brackets. The given sequence may be properly symmetrical and maybe not. In this problem, we are given a list of string that contains the bracket sequences and we have to find the number of pairs that can be concatenated to a single regular bracket sequence.

### Sample Examples

Input 1

string arr[] = {“)()”, “()(“, “()()”, “(())”}

Output: 2

Explanation − For the first and second strings we can concatenate the first string after the second string resulting in the regular bracket sequence. The third and fourth strings are already regular expressions, so we can easily add them or concatenate them to get another regular expression.

Input 2

string arr[] = {“()(“, “()(“}

Output: 0

Explanation − There are only two ways to add the string and both will produce the final string that will not be the regular string.

## Naive Approach

In this approach, we will consider all the pairs and find the best match for the current string. We will traverse over the strings using the nested for loop and find the pair that can be a regular expression. If we find any pair, then we will mark them as the used to not use later.

### Example

#include <bits/stdc++.h>
using namespace std;
// function to check if the string can make a regular expression
bool matched(string str1, string str2){
int n = str1.length(); // getting length of the string
int m = str2.length();
// first putting the first string in front
int k = 0;
for(int i=0;i<n;i++){
if(str1[i] == ')'){
k--;
}
else{
k++;
}
if(k < 0){
break;
}
}
if(k >= 0){
for(int i=0;i<m;i++){
if(str2[i] == '('){
k++;
}
else{
k--;
}
if(k < 0){
return false;
}
}
if(k == 0){
return true;
}
}
// updating the value of k to again check by putting second string after first
k = 0;
for(int i=0;i<m;i++){
if(str2[i] == ')'){
k--;
}
else{
k++;
}
if(k < 0){
return false;
}
}
for(int i=0;i<n;i++){
if(str1[i] == '('){
k++;
}
else{
k--;
}
if(k < 0){
return false;
}
}
if(k == 0){
return true;
}
return false;
}
int findRes(string arr[], int n){
vector<int>used(n); // vector to mark the already used string
int ans = 0;
// traversing over the array of string
for(int i=0; i<n; i++){
if(used[i] == 1){
continue; // current string is already concatenated
}
// for the current string finding the best match
for(int j=i+1; j < n; j++){
if(used[j] == 1){
continue; // current string is already used
}
// check if the current string can be matched with this string
if(matched(arr[i],arr[j])){
used[j] = 1;
ans++;
break;
}
}
}
return ans;
}
int main(){
// given string array;
string arr[] = {")()", "()(", "()()", "(())"};
int n = 4; // size of the given string array;
// calling the function
cout<<"The maximum number of strings that we can concatenate is "<<findRes(arr,n)<<endl;
return 0;
}


### Output

The maximum number of strings that we can concatenate is 2


### Time and Space Complexity

The time complexity of the above code is O(N*N*L), where N is the number of strings and L is the length of the strings.

The space complexity of the above code is O(N), as we are using an array to store the index of used strings.

## Efficient Approach

In this approach, we will find the number of required left and right parenthesis for the current string. If both left and right parenthesis are required then is cannot be used otherwise it can be paired with the string which needed the opposite side of the parenthesis. Let us see the code −

### Example

#include <bits/stdc++.h>
using namespace std;
// function to find the number of string can concatenate
int findRes(string arr[], int n){
// vector to store the left and rigth parenthesis required
vector<int>left(100), right(100);
// variable to count the number of strings that are already regular expressions
int reg = 0;
int ans = 0; // varaible to store the answer
// traversing over the strings
for(int i=0; i<n; i++){
// getting the required number of parenthesis on any side
int onLeft = 0, onRight = 0;
for(int j=0; j<arr[i].length(); j++){
if(arr[i][j] == '('){
onRight++;
}
else{
onRight--;
}
if(onRight < 0){
onLeft++;
onRight = 0;
}
}
if(onLeft == 0 && onRight == 0){
if(reg == 0){
reg++;
}
else{
reg = 0;
ans++;
}
}
else if(onLeft == 0){
if(left[onRight] == 0){
right[onRight]++;
}
else{
left[onRight]--;
ans++;
}
}
else if(onRight == 0){
if(right[onLeft] == 0){
left[onLeft]++;
}
else{
right[onLeft]--;
ans++;
}
}
}
return ans;
}
// main function
int main(){
// given string array;
string arr[] = {")()", "()(", "()()", "(())"};
int n = 4; // size of the given string array;
// calling the function
cout<<"The maximum number of strings that we can concatenate is "<<findRes(arr,n)<<endl;
return 0;
}


### Output

The maximum number of strings that we can concatenate is 2


### Time and Space Complexity

The time complexity of the above code is O(L*N), where L is the length of the strings and N is the number of strings.

The space complexity of the above code is O(L).

## Conclusion

In this tutorial, we have learned how to find the number of strings that can be concatenated to find the regular expression from the given set of strings. We have implemented two codes one with the time complexity of the O(L*N*N) and another with the efficient approach and time complexity of the O(L*N) by using some extra space.

Updated on: 17-May-2023

94 Views 