Now that I understand the question, here's another attempt. :)

sub align { my($hash, $seq) = @_; my $best = { totlen => 0 }; my @match; my $re = join '(.*?)', ($seq =~ /(\w)/g); for my $key (sort keys %$hash) { my $string = join '', @{ $hash->{$key} }; next unless $string =~ $re; my $offset = $-[0]; my $length = $+[0] - $offset; my $match = { key => $key, matched => substr($string, $offset, $length), totlen => $length, inserts => [ map $_ - $offset, @+[1 .. $#-] ], lengths => [ map $+[$_] - $-[$_], 1 .. $#+ ], }; push @match, $match; $best = $match if $match->{totlen} > $best->{totlen}; } return [ map { my $match = $_; my $string = $match->{matched}; for (reverse 0 .. $#{ $match->{lengths} }) { my $bestlen = $best->{lengths}[$_]; my $curlen = $match->{lengths}[$_]; if ($bestlen > $curlen) { substr($string, $match->{inserts}[$_], 0) = "-" x ($bestlen - +$curlen); } } $string; } @match ]; }

The idea is to apply the regexp to each string only once, and capture all relevant information at that point (also recording the longest match along the way), then take a second pass through all the matched substrings to add the hyphenation.

It isn't clear from the example what should happen if one of the strings to be modified already has a gap longer than that required, eg testing "ACD" against "ABICID" and "ACHHDH" - the code above would leave such a gap alone yielding

[ "ABICID", "A--CHHD" ]
, but if it should instead be truncated or marked in some other way you'd need to add an ... elsif ($bestlen < $curlen) ... chunk near the bottom.

Hugo


In reply to Re: Simple String Alignment by hv
in thread Simple String Alignment by monkfan

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.