给定长度为n的字符串R(x)表示具有给定语法下的一组单词的表达式:
- 对于每个小写字母x , R(x)= {x}
- 对于k≥2的表达式e_1,e_2,…,e_k , R({e_1,e_2,…,e_k})= R(e_1)∪R(e_2)∪∪R(e_k) 。
- 对于表达式e_1和e_2 , R(e_1 + e_2)= {a + b对于R(e_1)×R(e_2)}中的(a,b) ,其中+表示串联,而×表示笛卡尔积。
任务是找到表达式表示的单词的排序列表。
例子:
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”]
方法:根据给定的语法,字符串可以表示一组小写单词。令R(expr)表示由表达式表示的一组单词。考虑以下示例以了解该方法。
- 单个字母表示包含该单词的单例集。
R(“a”) = {“a”}
R(“w”) = {“w”} - 如果遇到两个或多个表达式的逗号分隔列表,请结合各种可能性。
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) - 在连接两个表达式时,采用两个单词之间可能的连接集,其中第一个单词来自第一个表达式,第二个单词来自第二个表达式。
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”}
请按照以下步骤解决问题:
- 遍历字符串中的字符,并检查以下三个条件:
- 如果{…}遇到,通过递归调用函数得到的结果里面{…}并做笛卡尔乘积与当前设置与返回的字符串集的字符串。
- 如果遇到逗号(,) ,则将当前字符串集推到结果中,然后清空当前字符串。
- 如果遇到字母,请使用当前的字符串集进行笛卡尔乘积运算。
- 最后,对结果集中的所有字符串进行排序,并仅打印唯一的字符串。
下面是上述方法的实现:
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)