📜  在给定的语法下打印由表达式表示的单词的排序列表

📅  最后修改于: 2021-04-23 19:51:30             🧑  作者: Mango

给定长度为n的字符串R(x)表示具有给定语法下的一组单词的表达式:

  • 对于每个小写字母xR(x)= {x}
  • 对于k≥2的表达式e_1,e_2,…,e_kR({e_1,e_2,…,e_k})= R(e_1)∪R(e_2)∪∪R(e_k)
  • 对于表达式e_1e_2R(e_1 + e_2)= {a + b对于R(e_1)×R(e_2)}中的(a,b) ,其中+表示串联,而×表示笛卡尔积。

任务是找到表达式表示的单词的排序列表。

例子:

方法:根据给定的语法,字符串可以表示一组小写单词。令R(expr)表示由表达式表示的一组单词。考虑以下示例以了解该方法。

  • 单个字母表示包含该单词的单例集。
  • 如果遇到两个或多个表达式的逗号分隔列表,请结合各种可能性。
  • 在连接两个表达式时,采用两个单词之间可能的连接集,其中第一个单词来自第一个表达式,第二个单词来自第二个表达式。

请按照以下步骤解决问题:

  • 遍历字符串中的字符,并检查以下三个条件:
    1. 如果{…}遇到,通过递归调用函数得到的结果里面{…}并做笛卡尔乘积与当前设置与返回的字符串集的字符串。
    2. 如果遇到逗号(,) ,则将当前字符串集推到结果中,然后清空当前字符串。
    3. 如果遇到字母,请使用当前的字符串集进行笛卡尔乘积运算。
  • 最后,对结果集中的所有字符串进行排序,并仅打印唯一的字符串。

下面是上述方法的实现:

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


输出:
ac ad ae bc bd be

时间复杂度: O(N 2 )
辅助空间: O(N)