Align-Sequence

 view release on metacpan or  search on metacpan

lib/Align/Sequence.pm  view on Meta::CPAN

package Align::Sequence;

use strict;
use 5.010_001;
our $VERSION = '0.01';

sub new {
  my $class = shift;
  # uncoverable condition false
  bless @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {}, ref $class || $class;
}

sub align {
  my ($self, $X, $Y) = @_;
  
  my $YPos;
  my $index;
  push @{ $YPos->{$_} },$index++ for @$Y;
  
  my $Xmatches;
  @$Xmatches = grep { exists( $YPos->{$X->[$_]} ) } 0..$#$X;
  
  my $Xcurrent = -1;
  my $Ycurrent = -1;
  my $Xtemp;
  my $Ytemp;
  
  my @L; # LCS
  my $R = 0;  # records the position of last selected symbol
  my $i;
  
  my $Pi;
  my $Pi1;
  
  my $hunk;
   
  for ($i = 0; $i <= $#$Xmatches; $i++) {
    $hunk = [];
    $Pi  =  $YPos->{$X->[$Xmatches->[$i]]}->[0] // $#$Y+1; # Position in Y of ith symbol
    $Pi1 =  ($i < $#$Xmatches && defined $YPos->{$X->[$Xmatches->[$i+1]]}->[0]) 
  	  ? $YPos->{$X->[$Xmatches->[$i+1]]}->[0] : -1; # Position in Y of i+1st symbol
    #print STDERR '$i: ',$i,' $Pi: ',$Pi,' $Pi1: ',$Pi1,' $R: ',$R,"\n";
    while ($Pi1 < $R && $Pi1 > -1) { 
      #print STDERR '$Pi1 < $R',"\n";
      shift @{$YPos->{$X->[$Xmatches->[$i+1]]}};
      $Pi1 = $YPos->{$X->[$Xmatches->[$i+1]]}->[0] // -1;
    }
    while ($Pi < $R && $Pi < $#$Y+1) {
      #print STDERR '$Pi < $R',"\n";
      shift @{$YPos->{$X->[$Xmatches->[$i]]}};
      $Pi =  $YPos->{$X->[$Xmatches->[$i]]}->[0] // $#$Y+1;
    }
    if ($Pi > $Pi1 && $Pi1 > $R) {
      $hunk = [$Xmatches->[$i+1],$Pi1];
      shift @{$YPos->{$X->[$Xmatches->[$i+1]]}};
      $R = $Pi1;
      $i = $i+1;
    } 
    elsif ($Pi <  $#$Y+1) {
      $hunk = [$Xmatches->[$i],$Pi];
      shift @{$YPos->{$X->[$Xmatches->[$i]]}}; 
      $R = $Pi;
    }

    if (scalar @$hunk) { 
      while ($Xcurrent+1 < $hunk->[0] ||  $Ycurrent+1 < $hunk->[1] ) {
        $Xtemp = '';
        $Ytemp = '';
        if ($Xcurrent+1 < $hunk->[0]) {
          $Xcurrent++;



( run in 2.637 seconds using v1.01-cache-2.11-cpan-483215c6ad5 )