Print a sorted list of words represented by the expression under the given grammar
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++
// 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; } |
Java
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 |
Python3
# 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#
// 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 |
Javascript
// 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)
Please Login to comment...