Skip to content
Related Articles
Open in App
Not now

Related Articles

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

Improve Article
Save Article
  • Last Updated : 29 Dec, 2022
Improve Article
Save Article

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:

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


Output:

ac ad ae bc bd be

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


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!