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

• Last Updated : 18 Jan, 2021

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.
• 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:

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

Output:

```ac ad ae bc bd be
```

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

My Personal Notes arrow_drop_up