Given a string R(x) of length n representing an expression having the set of words under the given grammar:
- For every lowercase letter x, R(x) = {x}
- For expressions e_1, e_2, …, e_k with k?2, R({e_1, e_2, …, e_k}) = R(e_1) ? R(e_2) ? … ? R(e_k).
- For expressions e_1 and e_2, R(e_1 + e_2) = {a + b for (a, b) in R(e_1) × R(e_2)}, where + denotes concatenation, and × denotes the Cartesian product.
The task is to find the sorted list of words that the expression represents.
Examples:
Input: “{{a, z}, a{b, c}, {ab, z}}”
Output: [ “a”, “ab”, “ac”, “z” ]
Explanation: Each distinct word is written only once in the final answer.
{a, z}, a{b, c}, {ab, z} ? {a, z}, {ab, ac}, {ab, z} ? [a, z, ab, ac]Input: “{a, b}{c, {d, e}}”
Output: [“ac”, “ad”, “ae”, “bc”, “bd”, “be”]
Approach: From the given grammar, strings can represent a set of lowercase words. Let R(expr) denote the set of words represented by the expression. Consider the following examples to understand the approach.
- Single letters represent a singleton set containing that word.
- If a comma-delimited list of 2 or more expressions is encountered, take the union of possibilities.
- While concatenating two expressions, take the set of possible concatenations between two words where the first word comes from the first expression and the second word comes from the second expression.
Follow the steps below to solve the problem:
-
Iterate over the characters of the string and check the following three conditions:
- If {…} is encountered, get the result inside {…} by recursively calling the function and do the Cartesian product with the current set of strings with the returned set of strings.
- If a comma(, ) is encountered, push the current set of strings to the result and empty the current strings.
- If a letter is encountered, do the Cartesian product with the current set of strings.
- Finally, sort all the strings in the result set and print only unique strings.
Below is the implementation of the above approach:
// C++ program to implement the above approach #include <bits/stdc++.h> using namespace std;
// Function to get the Cartesian product // of two set of strings vector<string> getProduct(vector<string>& lhs, vector<string>& rhs)
{ // If lhs is empty,
// return rhs
if (lhs.empty())
return rhs;
// Store the Cartesian product
// of two set of strings
vector<string> ret;
// Iterate over characters of both
// strings and insert Cartesian product
for ( auto sl : lhs)
for ( auto sr : rhs)
ret.push_back(sl + sr);
return ret;
} // Function to find the sorted list of words // that the expression represents vector<string> braceExpansion(string expression) { // Store the sorted list of words
// that the expression represents
vector<string> ret;
// Store the current set of strings
vector<string> cur;
// Append Comma
expression += ', ' ;
// Stores the length of expression
int len = expression.size();
// Iterate over the characters
// of the string(expression)
for ( int i = 0; i < len; ++i) {
// Stores the current character
char c = expression[i];
// If { is encountered, find
// its closing bracket, }
if (c == '{' ) {
// Store the characters inside
// of these brackets
string sub;
// Stores count of unbalanced '{''
int cnt = 1;
// Iterate over characters of
// expression after index i
while (++i < len) {
// If current character is '{'
if (expression[i] == '{' ) {
// Update cnt
++cnt;
}
// If current character is '}'
else if (expression[i] == '}' ) {
// Update cnt
--cnt;
}
// If cnt is equal to 0
if (cnt == 0)
break ;
// Append current character
sub += expression[i];
}
// Recursively call the function
// for the string, sub
vector<string> sub_ret
= braceExpansion(sub);
// Store the cartesian product of cur
// and sub_ret in cur
cur = getProduct(cur, sub_ret);
}
// If current character is Comma
else if (c == ', ' ) {
// Push cur result into ret
ret.insert(begin(ret),
begin(cur), end(cur));
// Clear the current set
// of strings
cur.clear();
}
else {
// Append the current character to tmp
vector<string> tmp(1, string(1, c));
// Store the cartesian product of
// tmp and cur in cur
cur = getProduct(cur, tmp);
}
}
// Sort the strings present in ret
// and get only the unique set of strings
sort(begin(ret), end(ret));
auto iter = unique(begin(ret), end(ret));
ret.resize(distance(begin(ret), iter));
return ret;
} // Driver Code int main()
{ // Given expression, str
string str = "{a, b}{c, {d, e}}" ;
// Store the sorted list of words
vector<string> res;
// Function Call
res = braceExpansion(str);
// Print the sorted list of words
for (string x : res) {
cout << x << " " ;
}
return 0;
} |
import java.util.*;
public class Main
{ // Function to get the Cartesian product
// of two set of strings
static List<String> getProduct(List<String> lhs, List<String> rhs)
{
// If lhs is empty, return rhs
if (lhs.size() == 0 ) return rhs;
// Store the Cartesian product
// of two set of strings
List<String> ret = new ArrayList<>();
// Iterate over characters of both
// strings and insert Cartesian product
for (String sl : lhs) {
for (String sr : rhs) {
ret.add(sl + sr);
}
}
return ret;
}
// Function to find the sorted list of words
// that the expression represents
static List<String> braceExpansion(String expression)
{
// Store the sorted list of words
// that the expression represents
List<String> ret = new ArrayList<>();
// Store the current set of strings
List<String> cur = new ArrayList<>();
// Append Comma
expression += ',' ;
// Stores the length of expression
int len = expression.length();
// Iterate over the characters
// of the string(expression)
for ( int i = 0 ; i < len; i++) {
// Stores the current character
char c = expression.charAt(i);
// If { is encountered, find
// its closing bracket, }
if (c == '{' ) {
// Store the characters inside
// of these brackets
StringBuilder sub = new StringBuilder();
// Stores count of unbalanced '{''
int cnt = 1 ;
// Iterate over characters of
// expression after index i
while (++i < len) {
// If current character is '{'
if (expression.charAt(i) == '{' ) {
// Update cnt
cnt++;
}
// If current character is '}'
else if (expression.charAt(i) == '}' ) {
// Update cnt
cnt--;
}
// If cnt is equal to 0
if (cnt == 0 ) break ;
// Append current character
sub.append(expression.charAt(i));
}
// Recursively call the function
// for the string, sub
List<String> subRet = braceExpansion(sub.toString());
// Store the cartesian product of cur
// and sub_ret in cur
cur = getProduct(cur, subRet);
}
// If current character is Comma
else if (c == ',' ) {
// Push cur result into ret
ret.addAll(cur);
// Clear the current set
// of strings
cur.clear();
} else {
// Append the current character to tmp
List<String> tmp = new ArrayList<>();
tmp.add( "" + c);
// Store the cartesian product of
// tmp and cur in cur
cur = getProduct(cur, tmp);
}
}
// Sort the strings present in ret
// and get only the unique set of strings
Collections.sort(ret);
long iter = ret.stream().distinct().count();
List<String> res = new ArrayList<String>();
for ( int i = 0 ; i < iter; i++)
res.add(ret.get(i));
return res;
}
// Driver Code
public static void main(String[] args)
{
// Given expression, str
String str = "{a,b}{c,{d,e}}" ;
// Store the sorted list of words
List<String> res = new ArrayList<String>();
// Function Call
res = braceExpansion(str);
// Print the sorted list of words
for (var ele : res)
System.out.print(ele + " " );
}
} // This code is contributed by phasing17 |
# Python program to implement the above approach # Function to get the Cartesian product # of two set of strings def getProduct(lhs, rhs):
# If lhs is empty,
# return rhs
if not lhs:
return rhs;
# Store the Cartesian product
# of two set of strings
ret = [];
# itersate over characters of both
# strings and insert Cartesian product
for sl in lhs:
for sr in rhs:
ret.append(sl + sr);
return ret;
# Function to find the sorted list of words # that the expression represents def braceExpansion( expression):
# Store the sorted list of words
# that the expression represents
ret = [];
# Store the current set of strings
cur = [];
# Append Comma
expression + = ',' ;
# Stores the lensgth of expression
lens = len (expression);
# itersate over the characters
# of the string(expression)
i = 0
while i < lens:
# Stores the current character
c = expression[i];
# If is encountered, find
# its closing bracket,
if (c = = '{' ) :
# Store the characters inside
# of these brackets
sub = "";
# Stores count of unbalanced '{'
cnt = 1 ;
# itersate over characters of
# expression after index i
while (i + 1 < lens):
i + = 1
# If current character is '{'
if (expression[i] = = '{' ) :
# Update cnt
cnt + = 1 ;
# If current character is '{'
elif (expression[i] = = '}' ) :
# Update cnt
cnt - = 1 ;
# If cnt is equal to 0
if (cnt = = 0 ):
break ;
# Append current character
sub + = expression[i];
# Recursively call the function
# for the string, sub
sub_ret = braceExpansion(sub);
# Store the cartesian product of cur
# and sub_ret in cur
cur = getProduct(cur, sub_ret);
# If current character is Comma
elif (c = = ',' ) :
# append cur result into ret
ret + = cur
# Clear the current set
# of strings
cur = []
else :
# Append the current character to tmp
tmp =
# Store the cartesian product of
# tmp and cur in cur
cur = getProduct(cur, tmp);
i + = 1
# Sort the strings present in ret
# and get only the unique set of strings
ret.sort()
iters = len ( set (ret))
return ret[:iters];
# Driver Code # Given expression, str strs = "{a,b}{c,{d,e}}" ;
# Store the sorted list of words res = [];
# Function Call res = braceExpansion(strs);
# Print the sorted list of words print ( * res)
# This code is contributed by phasing17 |
// C# program to implement the above approach using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{ // Function to get the Cartesian product
// of two set of strings
static List< string > getProduct(List< string > lhs, List< string > rhs)
{
// If lhs is empty,
// return rhs
if (lhs.Count == 0)
return rhs;
// Store the Cartesian product
// of two set of strings
List< string > ret = new List< string >();
// Iterate over characters of both
// strings and insert Cartesian product
foreach ( var sl in lhs)
foreach ( var sr in rhs)
ret.Add(sl + sr);
return ret;
}
// Function to find the sorted list of words
// that the expression represents
static List< string > braceExpansion( string expression)
{
// Store the sorted list of words
// that the expression represents
List< string > ret = new List< string >();
// Store the current set of strings
List< string > cur = new List< string >();
// Append Comma
expression += ',' ;
// Stores the length of expression
var len = expression.Length;
// Iterate over the characters
// of the string(expression)
int i;
for (i = 0; i < len; ++i) {
// Stores the current character
var c = expression[i];
// If { is encountered, find
// its closing bracket, }
if (c == '{' ) {
// Store the characters inside
// of these brackets
var sub = "" ;
// Stores count of unbalanced '{''
var cnt = 1;
// Iterate over characters of
// expression after index i
while (++i < len) {
// If current character is '{'
if (expression[i] == '{' ) {
// Update cnt
++cnt;
}
// If current character is '}'
else if (expression[i] == '}' ) {
// Update cnt
--cnt;
}
// If cnt is equal to 0
if (cnt == 0)
break ;
// Append current character
sub += expression[i];
}
// Recursively call the function
// for the string, sub
var sub_ret
= braceExpansion(sub);
// Store the cartesian product of cur
// and sub_ret in cur
cur = getProduct(cur, sub_ret);
}
// If current character is Comma
else if (c == ',' ) {
// Push cur result into ret
foreach ( var ele in cur)
ret.Add(ele);
// Clear the current set
// of strings
cur.Clear();
}
else {
// Append the current character to tmp
List< string > tmp = new List< string >();
tmp.Add( "" + c);
// Store the cartesian product of
// tmp and cur in cur
cur = getProduct(cur, tmp);
}
}
// Sort the strings present in ret
// and get only the unique set of strings
ret.Sort();
int iter = ret.Distinct().ToList().Count;
return ret.GetRange(0, iter);
}
// Driver Code
public static void Main( string [] args)
{
// Given expression, str
var str = "{a,b}{c,{d,e}}" ;
// Store the sorted list of words
List< string > res = new List< string >();
// Function Call
res = braceExpansion(str);
// Print the sorted list of words
foreach ( var ele in res)
Console.Write(ele + " " );
}
} // This code is contributed by phasing17 |
// JS program to implement the above approach // Function to get the Cartesian product // of two set of strings function getProduct(lhs, rhs)
{ // If lhs is empty,
// return rhs
if (lhs.length == 0)
return rhs;
// Store the Cartesian product
// of two set of strings
let ret = [];
// Iterate over characters of both
// strings and insert Cartesian product
for (let sl of lhs)
for (let sr of rhs)
ret.push(sl + sr);
return ret;
} // Function to find the sorted list of words // that the expression represents function braceExpansion( expression)
{ // Store the sorted list of words
// that the expression represents
let ret = [];
// Store the current set of strings
let cur = [];
// Append Comma
expression += ',' ;
// Stores the length of expression
let len = expression.length;
// Iterate over the characters
// of the string(expression)
let i;
for (i = 0; i < len; ++i) {
// Stores the current character
let c = expression[i];
// If { is encountered, find
// its closing bracket, }
if (c == '{' ) {
// Store the characters inside
// of these brackets
let sub = "" ;
// Stores count of unbalanced '{''
let cnt = 1;
// Iterate over characters of
// expression after index i
while (++i < len) {
// If current character is '{'
if (expression.charAt(i) == '{ ') {
// Update cnt
++cnt;
}
// If current character is ' } '
else if (expression.charAt(i) == ' } ') {
// Update cnt
--cnt;
}
// If cnt is equal to 0
if (cnt == 0)
break;
// Append current character
sub += expression.charAt(i);
}
// Recursively call the function
// for the string, sub
let sub_ret
= braceExpansion(sub);
// Store the cartesian product of cur
// and sub_ret in cur
cur = getProduct(cur, sub_ret);
}
// If current character is Comma
else if (c == ' ,') {
// Push cur result into ret
ret.push(...cur)
// Clear the current set
// of strings
cur = []
}
else {
// Append the current character to tmp
let tmp =
// Store the cartesian product of
// tmp and cur in cur
cur = getProduct(cur, tmp);
}
}
// Sort the strings present in ret
// and get only the unique set of strings
ret.sort((a, b) => a.localeCompare(b))
let iter = ( new Set(ret)).length
ret = ret.slice(0, iter);
return ret;
} // Driver Code // Given expression, str let str = "{a,b}{c,{d,e}}" ;
// Store the sorted list of words let res = []; // Function Call res = braceExpansion(str); // Print the sorted list of words console.log(res.join( " " ))
// This code is contributed by phasing17 |
ac ad ae bc bd be
Time Complexity: O(N2)
Auxiliary Space: O(N)