enumerate all adjecent substrings in the file

X

xhoster

puzzlecracker said:
I have a file and I want to list all substirngs e.x.

I hope it is a pretty small file.
abs =[a ab abs bs ]

What about b and s?


# doesn't include the empty string.
# (If it did, how many times should it be include?)
while (length $string) {
foreach (1..length $string) {
print substr $string,0,$_;
};
substr $string,0,1,'';
};

Xho
 
B

Brian McCauley

# doesn't include the empty string.
# (If it did, how many times should it be include?)
while (length $string) {
foreach (1..length $string) {
print substr $string,0,$_;
};
substr $string,0,1,'';
};

For this particular requirement the nested loop approach is possibly
the most efficient but there is also the approach of finding all
matches for the pattern /.+/.

sub all_matches {
my ($string, $pattern) = @_;
local our @strings; # Lexicals don't play nicely with (?{})
my $capture = qr/(?{ push @strings => $1 })/;
$string =~ /($pattern)$capture(?!)/;
@strings;
}

print join ' ', all_matches('abs',qr/.+/);
 
A

Anno Siegel

puzzlecracker said:
I have a file and I want to list all substirngs e.x.

abs =[a ab abs bs ]

That aren't all substrings.

print "$_\n" for map $str =~ /.{$_}/g, 1 .. length $str;

Anno
 
R

Ron Savage

On Mon, 12 Dec 2005 01:21:31 +1100, (e-mail address removed)-berlin.de wrote:

Hi Anno
print "$_\n" for map $str =~ /.{$_}/g, 1 .. length $str;

Neat, but you should have tested it:

#!/usr/bin/perl
use strict;
use warnings;
# -----------
my($str) = 'abc';
print "$_\n" for map $str =~ /.{$_}/g, 1 .. length $str;

produces

a
b
c
ab
abc

Where is bc?
 
A

Anno Siegel

Ron Savage said:
On Mon, 12 Dec 2005 01:21:31 +1100, (e-mail address removed)-berlin.de wrote:

Hi Anno


Neat, but you should have tested it:

#!/usr/bin/perl
use strict;
use warnings;
# -----------
my($str) = 'abc';
print "$_\n" for map $str =~ /.{$_}/g, 1 .. length $str;

produces

a
b
c
ab
abc

Where is bc?

Oh, right. Overlapping substrings of each length are missing. Trying
to fix it gave me this:

for ( 0 .. length( $str) - 1 ) {
print "$1$2\n" while $str =~ /(.)(?=(.{$_}))/g;
}

Scratch it.

Anno
 
J

John W. Krahn

Anno said:
Oh, right. Overlapping substrings of each length are missing. Trying
to fix it gave me this:

for ( 0 .. length( $str) - 1 ) {
print "$1$2\n" while $str =~ /(.)(?=(.{$_}))/g;
}

Or just:

print "$_\n" for map $str =~ /(?=(.{$_}))/g, 1 .. length $str;



John
 
A

Anno Siegel

John W. Krahn said:
Or just:

print "$_\n" for map $str =~ /(?=(.{$_}))/g, 1 .. length $str;

Ah, thanks... much better. Empty matches don't match twice at the same
place, that's why it makes progress without ever matching anything
substantial.

Anno
 
D

Dr.Ruud

John W. Krahn:
print "$_\n" for map $str =~ /(?=(.{$_}))/g, 1 .. length $str;

Variant:

#!/usr/bin/perl

use strict;
use warnings;
{
local($,, $\) = ("\t", "\n");

my $str = 'abcabc';

print "$_" for map $str =~ /(?=(.{$_}))/g, 1..length $str;
print '--';
print "$_" for map $str =~ /(?=(.{$_})(?!.*\1))/g, 1..length $str;
}
 
A

Anno Siegel

Dr.Ruud said:
John W. Krahn:


Variant:

#!/usr/bin/perl

use strict;
use warnings;
{
local($,, $\) = ("\t", "\n");

my $str = 'abcabc';

print "$_" for map $str =~ /(?=(.{$_}))/g, 1..length $str;
print '--';
print "$_" for map $str =~ /(?=(.{$_})(?!.*\1))/g, 1..length $str;
}

Ah, you're building the set of unique substrings instead of the list
of all of them.

The interesting part is that this solves a problem with "unique" in
the specification without using a hash. A hash solution looks more
complicated, at least when forced into a single statement:

{
local($,, $\) = ("\t", "\n");
my $str = 'abcabc';

print for keys %{
{
map { $_ => 1 }
map $str =~ /(?=(.{$_}))/g, 1..length $str
}
};
}

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top