Using regular expressions to find a word with the five letters abcde, each letter appearing exactly once, in any order, with no breaks in between

前端 未结 3 1888
梦谈多话
梦谈多话 2021-02-13 06:45

For example, the word debacle would work because of debac, but seabed would not work because: 1. there is no c in any 5-character sequence tha

相关标签:
3条回答
  • 2021-02-13 07:28
    /
       (?= .{0,4}a )
       (?= .{0,4}b )
       (?= .{0,4}c )
       (?= .{0,4}d )
       (?= .{0,4}e )
    /xs
    

    It's probably results in faster matching to generate a pattern from all combinations.

    use Algorithm::Loops qw( NextPermute );
    my @pats;
    my @chars = 'a'..'e';
    do { push @pats, quotemeta join '', @chars; } while NextPermute(@chars);
    my $re = join '|', @pats;
    

    abcde|abced|abdce|abdec|abecd|abedc|acbde|acbed|acdbe|acdeb|acebd|acedb|adbce|adbec|adcbe|adceb|adebc|adecb|aebcd|aebdc|aecbd|aecdb|aedbc|aedcb|bacde|baced|badce|badec|baecd|baedc|bcade|bcaed|bcdae|bcdea|bcead|bceda|bdace|bdaec|bdcae|bdcea|bdeac|bdeca|beacd|beadc|becad|becda|bedac|bedca|cabde|cabed|cadbe|cadeb|caebd|caedb|cbade|cbaed|cbdae|cbdea|cbead|cbeda|cdabe|cdaeb|cdbae|cdbea|cdeab|cdeba|ceabd|ceadb|cebad|cebda|cedab|cedba|dabce|dabec|dacbe|daceb|daebc|daecb|dbace|dbaec|dbcae|dbcea|dbeac|dbeca|dcabe|dcaeb|dcbae|dcbea|dceab|dceba|deabc|deacb|debac|debca|decab|decba|eabcd|eabdc|eacbd|eacdb|eadbc|eadcb|ebacd|ebadc|ebcad|ebcda|ebdac|ebdca|ecabd|ecadb|ecbad|ecbda|ecdab|ecdba|edabc|edacb|edbac|edbca|edcab|edcba

    (This will get optimised into a trie in Perl 5.10+. Before 5.10, use Regexp::List.)

    0 讨论(0)
  • 2021-02-13 07:28
    #! perl -lw
    for (qw(debacle seabed feedback)) {
        print if /([a-e])(?!\1)
            ([a-e])(?!\1)(?!\2)
            ([a-e])(?!\1)(?!\2)(?!\3)
            ([a-e])(?!\1)(?!\2)(?!\3)(?!\4)
            ([a-e])/x;
    }
    
    0 讨论(0)
  • 2021-02-13 07:35

    Your solution is clever but unfortunately [a-e^...] doesn't work, as you found. I don't believe there is a way to mix regular and negated character classes. I can think of a workaround using lookaheads though:

        /(([a-e])(?!\2)([a-e])(?!\2)(?!\3)([a-e])(?!\2)(?!\3)(?!\4])([a-e])(?!\2)(?!\3)(?!\4])(?!\5)([a-e]))/
    

    See it here: http://rubular.com/r/6pFrJe78b6.

    UPDATE: Mob points out in the comments below, that alternation can be used to compact the above:

        /(([a-e])(?!\2)([a-e])(?!\2|\3)([a-e])(?!\2|\3|\4])([a-e])(?!\2|\3|\4|\5)([a-e]))/
    

    The new demo: http://rubular.com/r/UUS7mrz6Ze.

    0 讨论(0)
提交回复
热议问题