in reply to Re: Simple String Alignment
in thread Simple String Alignment

Adrade,
Thanks so much for your reply. I've included your part in my code. Somehow your approach doesn't consider the maximum span *in the given query*.
For example with query: "ACD" it gives
S4 ABIC S1 AB-C S2 A--C
i.e it left out the "D" for alignment (kindly see answers above). In other case, given query "AB" it over-aligned them, it gives:
S4 ABICID S2 A--C-D S1 AB-C-D
Is there any way I can go about it in your code. Hope to hear from you again.

Update: Finally! with some tweak suggested by Adrade below. I can get the problem SOLVED! Many thanks for the rest of you, especially Adrade. Don't know what to say! For those who are interested in the final form of the code, check this out:
# With major improvement by "canonizable" Adrade :-) sub align_v3 { my ($hashref,$seq) = @_; my @in = split(/\s/,$seq); my $test = join('(.*?)',@in); my @hyph_padded_seq; my @sequences; my $reduce; for (keys %$hashref) { $reduce = length(${$hashref->{$_}}[0]); last; } for my $key( sort {$a cmp $b} keys(%$hashref)) { my $string = join('',@{$hashref->{$key}}); if($string =~ $test) { push(@sequences, $hashref->{$key}); } } my $regex = '.*'.join('(.*)',@in).'.*'; my @in_the_running; my $biglen = 0; for (@sequences) { my @letters = @$_; # split(//,$_); s/.*($in[0].*$in[$#in]).*/$1/; my ($first, $last) = (0,0); for (@letters) { last if $_ eq $in[0]; $first++; } for (reverse @letters) { last if $_ eq $in[$#in]; $last++; } $last = $#letters - $last; @letters = @letters[$first..$last]; my $asstr = join('',@letters); if ((my @gaps) = ($asstr =~ m/$regex/o)) { my $len = length(join('',@gaps)) / $reduce; if ($len > $biglen) { unshift(@in_the_running, [ @letters ]); $biglen = length(join('',@gaps)); } elsif ($len == $biglen) { unshift(@in_the_running, [ @letters ]); } else { push(@in_the_running, [ @letters ]); } } } #print @{$in_the_running[0]}, "\n"; push @hyph_padded_seq, join('',@{$in_the_running[0]}); my @base = @{$in_the_running[0]}; for my $seqno (1..$#in_the_running) { # my @seq = split(//,$in_the_running[$seqno]); my @seq = @{$in_the_running[$seqno]}; my $count = $#base; my @disp; for my $q (reverse @base) { if (($seq[$#seq] eq $q) || ($count == $#seq)) { push(@disp, pop(@seq)); } else { push(@disp, '-' x $reduce); } $count--; } push @hyph_padded_seq, join('', reverse(@disp)); #print reverse(@disp), "\n"; } return @hyph_padded_seq; } # A hash version can be found here: http://paste.phpfi.com/61624
Regards,
Edward

Replies are listed 'Best First'.
Re^3: Simple String Alignment
by Adrade (Pilgrim) on May 11, 2005 at 02:51 UTC
    Dear Edward,

    I think I have discovered the problem. In my code, I did a pop(@in) just to remove the newline that occurs when the user types in the letters. This was accidentally left in your code. If you comment out line 41, everything should work fine!

    I hope this helps - let me know how it turns out!

    Best
      -Adam

    Update: The finally (maybe :-) revised code (that should do everything correctly) can be found here.

    Another Update! Hehe - ok... lets hope this hits the mark: Code is here

    YA-Update: The correct and final code is in the above post. Yay.

    Be well,
      -Adam