 Open in App
Not now

# Print a sorted list of words represented by the expression under the given grammar

• Last Updated : 29 Dec, 2022

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”]

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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:

Below is the implementation of the above approach:

## C++

 `// C++ program to implement the above approach` `#include ` `using` `namespace` `std;`   `// Function to get the Cartesian product` `// of two set of strings` `vector getProduct(vector& lhs,` `                          ``vector& rhs)` `{`   `    ``// If lhs is empty,` `    ``// return rhs` `    ``if` `(lhs.empty())` `        ``return` `rhs;`   `    ``// Store the Cartesian product` `    ``// of two set of strings` `    ``vector 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 braceExpansion(string expression)` `{`   `    ``// Store the sorted list of words` `    ``// that the expression represents` `    ``vector ret;`   `    ``// Store the current set of strings` `    ``vector 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 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 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 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 getProduct(List lhs, List rhs)` `  ``{` `    `  `    ``// If lhs is empty, return rhs` `    ``if` `(lhs.size() == ``0``) ``return` `rhs;`   `    ``// Store the Cartesian product` `    ``// of two set of strings` `    ``List 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 braceExpansion(String expression)` `  ``{` `    `  `    ``// Store the sorted list of words` `    ``// that the expression represents` `    ``List ret = ``new` `ArrayList<>();`   `    ``// Store the current set of strings` `    ``List 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 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 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 res = ``new` `ArrayList();` `    ``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 res = ``new` `ArrayList();`   `    ``// 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`

Output:

`ac ad ae bc bd be`

Time Complexity: O(N2)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Related Articles