【问题标题】:Generate All Possible Matches of a Regular Expression [closed]生成正则表达式的所有可能匹配项[关闭]
【发布时间】:2015-05-05 21:46:18
【问题描述】:

如何导出正则表达式的所有可能匹配项

例如:

((a,b,c)o(m,v)p,b)

从上面的表达式生成的字符串是:

安放

砰砰

比较

aovp

bovp

冠状病毒

b

【问题讨论】:

  • 构建一个接受正则表达式语言的 DFA,执行 BFS,并且仅在您处于接受状态时才输出。存储已输出的单词,断开 BFS 中重复已输出单词的任何分支。
  • 无论您选择哪种解决方案,都不要在a+ 上运行它。
  • 感谢 G.Bach 和 Sebastian。问题已解决。
  • 评论:“我已经设法对用逗号分隔的字符串进行分区并运行递归算法,但产品以相反的顺序打印。” OP已将其编辑为问题。我已将其回滚并将其放在这里,以便让未来的读者更清楚地了解这个问题。

标签: c++ string algorithm expansion string-interpolation


【解决方案1】:

您的步骤非常简单,但实施它们可能需要一些工作:

  1. 创建一个递归函数,提取第一组括号之间的字符串:https://stackoverflow.com/a/28863720/2642059
  2. 在函数中将','上的字符串拆分为vector<string>并返回:https://stackoverflow.com/a/28880605/2642059
  3. 如果由于嵌套括号而需要递归,则在返回 test 之前,必须为从递归函数返回的每个可能组合添加一个字符串

编辑:

假设我的输入字符串是“(bl(ah,eck,le),yap)”

  • 第一个函数将提取string: "bl(ah,eck,le),yap"
  • 在返回之前它会搜索嵌套括号,这会导致它递归:
    • 第二个函数将提取string: "ah,eck,le"
    • 在返回之前,它会搜索嵌套的括号,但没有找到
    • 它会返回一个vector<string>: ["ah","eck","le"]
  • 第一个函数现在将包含:"bl["ah","eck","le"],yap"
  • 它找不到要提取的括号,因此它会扩展所有内部组合:“[”blah”,”bleck”,”blle”],yap”
  • 它现在可以拆分字符串并返回:["blah","bleck","blle","yap"]

第一个函数的返回就是你的结果。

编辑:

很高兴你解决了它我写了一个两个状态机来解决它所以我想我可以把它贴在这里供你比较:

const char* extractParenthesis(const char* start, const char* finish){
    int count = 0;

    return find_if(start, finish, [&](char i){
        if (i == '('){
            count++;
        }
        else if (i == ')'){
            count--;
        }
        return count <= 0; });
}

vector<string> split(const char* start, const char* finish){
    const char delimiters[] = ",(";
    const char* it;
    vector<string> result;

    do{
        for (it = find_first_of(start, finish, begin(delimiters), end(delimiters));
            it != finish && *it == '(';
            it = find_first_of(extractParenthesis(it, finish) + 1, finish, begin(delimiters), end(delimiters)));
        auto&& temp = interpolate(start, it);
        result.insert(result.end(), temp.begin(), temp.end());
        start = ++it;
    } while (it <= finish);
    return result;
}

vector<string> interpolate(const char* start, const char* finish){
    vector<string> result{ 1, string{ start, find(start, finish, '(') } };

    for (auto it = start + result[0].size();
        it != finish;
        it = find(++start, finish, '('),
        for_each(result.begin(), result.end(), [&](string& i){ i += string{ start, it }; })){
        start = extractParenthesis(it, finish);

        auto temp = split(next(it), start);
        const auto size = result.size();

        result.resize(size * temp.size());

        for (int i = result.size() - 1; i >= 0; --i){
            result[i] = result[i % size] + temp[i / size];
        }
    }
    return result;
}

根据您的编译器,您需要转发声明这些,因为它们相互调用。如果输入字符串格式不正确,这也会非常崩溃。而且它不能处理转义的控制字符。

无论如何你都可以这样称呼它:

const char test[] = "((a,b,c)o(m,v)p,b)";
auto foo = interpolate(begin(test), end(test));

for (auto& i : foo){
    cout << i << endl;
}

【讨论】:

  • 能否请您提供一个伪代码或详细的步骤号。 3
  • @NilutpalBorgohain 我已经稍微扩展了答案,但如前所述,这需要一些工作。这是一个糟糕的问题,因为它实际上是在要求其他人为你做你的工作。如果您还有其他问题,我建议您开始解决此问题,当您有东西要展示时,询问如何解决您遇到的任何问题作为一个新问题。
  • 谢谢乔纳森,问题已经解决了。
  • @NilutpalBorgohain 干得好!那是一个有趣的问题。我们可能会因发布没有附加工作的问题的解决方案而获得一些(更多)反对票,但我认为查看我的工作可能对您有所帮助。如果您有任何问题,请告诉我。另外,如果这个答案解决了你的问题,请点击它旁边的复选标记。
猜你喜欢
  • 2011-10-02
  • 1970-01-01
  • 2021-06-11
  • 2013-01-25
  • 1970-01-01
  • 2011-02-23
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多