YuckFoo has asked for the wisdom of the Perl Monks concerning the following question:

Howdy Monks,

I'm looking for a better (cleaner) way to do this. I'd like to get a list of unique substrings formed by removing one character from a string.

aabcc ==> abcc, aacc, aabc

I can't believe I had to use two temporary lists and a hash to do this. Golfers are welcome.

YuckFoo

#!/usr/bin/perl use strict; my $list = sslist('aabcc'); for (@{$list}) { print "$_\n"; } sub sslist { my ($str) = @_; my (@list, %uniq); my @chars = split('', $str); for my $i (0..@chars-1) { my @temp = @chars; splice(@temp, $i, 1); my $key = join('', @temp); if (!$uniq{$key}++) { push (@list, $key); } } return \@list; }

Replies are listed 'Best First'.
Re: List of substrings
by kvale (Monsignor) on Jun 24, 2002 at 18:14 UTC
    This one uses only a temp scalar and a hash:
    use strict; my $string = shift; my %seen; map { my $temp = $string; substr $temp, $_, 1, ""; print "$temp\n" unless $seen{$temp}++; } (0..(length $string) - 1);
    -Mark
      I was about to post a similar solution, but you beat me to it ;-P

      The only comment I would make is use foreach instead of map. In void context map will build a list to return, which just gets thrown away.

        That's a good point. I was going to use the map to build a substring array, but changed my strategy halfway through and didn't clean up. Here is a corrected version:
        use strict; my $string = shift; my %seen; foreach (0..(length $string) - 1) { my $temp = $string; substr $temp, $_, 1, ""; print "$temp\n" unless $seen{$temp}++; }
        Thanks!

        -Mark
Re: List of substrings
by japhy (Canon) on Jun 24, 2002 at 19:01 UTC
    And a regex will lead them (at 47 characters):
    sub sslist { #2345678901234567890123456789012345678901234567 my$s=pop;$s=~s/(.)(\1*)/push@_,"$`$2$'"/egs;\@_ }

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;