=pod @longest = pinyan_UCS($string) This function returns the set of the longest substrings in a given string. It seems rather efficient, even though it calls C quite a bit. I found that using a hash to figure if I'd seen a character had adverse effects. =cut sub pinyan_UCS { my $str = shift; my $len = length $str; my ($diff,$biggest) = (0,0); my ($jump,@ahead,@matches); for (my $i = 0; $i < $len; ) { my $match = [ $i, $len ]; if ($len - $i >= $biggest) { for (my $k = $i; $k < $match->[1]; $k++) { $ahead[$k] ||= index($str, substr($str,$k,1), $k+1); if ($ahead[$k] != -1 and $match->[1] > $ahead[$k]) { $match->[1] = $ahead[$k]; $jump = $k; } } $diff = $match->[1] - $match->[0]; if ($diff > $biggest) { ($biggest,@matches) = ($diff,$match) } elsif ($diff == $biggest) { push @matches, $match; } } else { last } $i = ++$jump; } return map substr($str, $_->[0], $_->[1] - $_->[0]), @matches; }