Saurabh Shrivastava
Saurabh Shrivastava

Reputation: 1484

Use Perl to extract all possible substrings

$str="abcde"

and i want output array as

a,b,c,d,e,ab,bc,cd,de,abc,bcd,cde,abcd,bcde,abcde.

ie moving from left to right, all possible combinations of all different lengths.

Also, additional function to remove duplicate elements, like

$str="abcdd"

may have many duplicate items in array

This is what I have tried

for ($j=1;$j<=$n;$j++) {
   my @tmp = unpack("(A$j)*", $seq);
   print "@tmp\n";
} 

Upvotes: 1

Views: 514

Answers (2)

Miller
Miller

Reputation: 35198

The only trick to this problem is knowing that one needs to use a Positive lookahead assertion in order to find regular expression matches that overlap.

If you then only want unique substrings, then either read perlfaq4 - How can I remove duplicate elements from a list or array? or use List::MoreUtils uniq

use strict;
use warnings;

use List::MoreUtils qw(uniq);

for my $string (qw(abcde abcdd)) {
    my @list = uniq map { $string =~ /(?=(.{$_}))/g } ( 1 .. length $string );
    print "$string - ", join( ',', @list ), "\n";
}

Outputs:

abcde - a,b,c,d,e,ab,bc,cd,de,abc,bcd,cde,abcd,bcde,abcde
abcdd - a,b,c,d,ab,bc,cd,dd,abc,bcd,cdd,abcd,bcdd,abcdd

Upvotes: 1

Borodin
Borodin

Reputation: 126722

This is an extremely simple problem. This program solves it in a single line, although a double loop would probably be clearer.

use strict;
use warnings;
use 5.010;

my $str = 'abcde';

my @list;

push @list, $str =~ /(?=(.{$_}))/g for 1 .. length $str;

say join ',', @list;

output

a,b,c,d,e,ab,bc,cd,de,abc,bcd,cde,abcd,bcde,abcde

Upvotes: 3

Related Questions