# 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.
R(“a”) = {“a”}

R(“w”) = {“w”} - If a comma-delimited list of 2 or more expressions is encountered, take the union of possibilities.
R(“{a, b, c}”) = {“a”, “b”, “c”}

R(“{{a, b}, {b, c}}”) = {“a”, “b”, “c”} (notice the final set only contains each word at most once) - 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.
R(“{a, b}{c, d}”) = {“ac”, “ad”, “bc”, “bd”}

R(“a{b, c}{d, e}f{g, h}”) = {“abdfg”, “abdfh”, “abefg”, “abefh”, “acdfg”, “acdfh”, “acefg”, “acefh”}

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.

- If
- 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;` `}` |

**Output:**

ac ad ae bc bd be

**Time Complexity: **O(N^{2})**Auxiliary Space:** O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**

In case you wish to attend **live classes **with experts, please refer **DSA Live Classes for Working Professionals **and **Competitive Programming Live for Students**.