代码之家  ›  专栏  ›  技术社区  ›  Cory Nezin

为什么Regex(C++)取指数时间?

  •  8
  • Cory Nezin  · 技术社区  · 7 年前

    我正在做一些教科书中的regex问题,其中包括:

    “[匹配]所有以整数开头、以单词结尾的字符串。”

    为此,我编写了以下正则表达式:

    ^[0-9]+\s.*+\b[a-zA-Z]+$
    

    但是,当我在C++中用下面的代码实现这一点时:

    #include <iostream>
    #include <string>
    #include <regex>
    #include <time.h>
    
    int main(){
        clock_t t;
        bool match;
        std::string exp = "^[0-9]+\\s.*+\b[a-zA-Z]+$";
        std::string str = "1 a few words 1";
        std::string s (str);
        std::smatch m;
        std::regex e (exp);
        while (true){
            t = clock();
            match = std::regex_match(s, m, e); 
            s = s + "1";
            std::cout << clock() - t << std::endl;
        }   
    }
    

    每次迭代所用的CPU时间为:

    1 1181529
    2 3398674
    3 10102763
    4 30370932
    5 92491242
    

    看起来很复杂 O( 3^n )

    为什么会这样?这个表达有什么我做错的吗?

    如果我使用类似“1 a 1”的字符串,但使用较小的常量,则增长因子是相同的。

    编辑:我看到的问题是我有一个 .*+ 哎呀!不过,我不知道这为什么会导致指数行为。

    2 回复  |  直到 7 年前
        1
  •  7
  •   Jerry Coffin    7 年前

    .*+\b .*\\b

    .* +

    \b

        2
  •  0
  •   sweting    7 年前