Процентное изменение расстояния от массива


Я пытаюсь получить процент расстояния редактирования от группы последовательностей. Пока вот что у меня есть:

#!/usr/bin/perl -w
use strict;
use Text::Levenshtein qw(distance);

my @sequence = qw(CA--------W----------------------EKDRRTEAF---F------ 
CA--------W----------------------EKDRRTEAF---F------ 
CA--------S-------------------SLVFGQGDNIQY---F------  
RA--------S-------------------SLIYSP----LH---F------);


foreach my $list (@sequence){
    my @distance = distance($list, @sequence);
    my @length = $list =~ tr/[A-Z]///;
}

Я могу получить расстояние редактирования с @distance и длину каждой последовательности, основываясь на буквах с @length. В случае печати результаты выглядят следующим образом:

@distance

0 0 13 14
0 0 13 14
13 13 0 11 
14 14 11 0

@length

13
13
16
12

Поскольку каждая строка @length эквивалентна каждой строке @sequence, при сравнении двух строк я хотел бы использовать самую большую @length, чтобы получить процент. Таким образом, при наличии расстояния редактирования между второй и третьей последовательностью он будет использовать длину 16, а не 13, Чтобы получить процент. То, что я думаю, должно произойти, это вызвать только два элемента массива @length и выбрать больший, чтобы затем поместить в процент, возможно, используя оператор if.

Я знаю, что этот код неверен, но в целом это идея, которую я ищу:

foreach my  $list (@sequence){
        my @distance = distance($list, @sequence);      
        my @length = $list =~ tr/[A-Z]//;                # / syntax hilite fix

        foreach my $item(@distance){
                foreach @length {
                        my $num1 = if $length[0] >= $length[1];
                                 print "$item/$num1n";
                        else my $num2 = $length[1] >= $length[0];
                                print "$item/$num2n";
                }
        }
}

Ответ должен выглядеть примерно так, как показано ниже:

0  0 .8125  1.0769
0  0  .8125  1.0769
.8125  .8125  0  .6875
1.0769  1.0769  .6875  0
1 3

1 ответ:

Попробуйте это. Подводя итог: мы вычисляем расстояния редактирования между парами веревка. Для каждой пары мы хотим определить долю расстояния и максимальное количество символов (A-Z). Максимальное количество символов считается максимальным для двух элементов в паре.

use strict;
use warnings;

use Text::Levenshtein qw(distance);

my @sequence = qw(
        CA--------W----------------------EKDRRTEAF---F------
        CA--------W----------------------EKDRRTEAF---F------
        CA--------S-------------------SLVFGQGDNIQY---F------
        RA--------S-------------------SLIYSP----LH---F------
);

my @length = map { tr/[A-Z]// } @sequence;

for my $i (0..$#sequence) {
    my $list = $sequence[$i];
    my @distance = distance($list, @sequence);
    my $num1 = $length[$i];
    for my $j (0..$#distance) {
        my $item = $distance[$j];
        my $num2 = $length[$j];
        my $num = ( $num2 > $num1 ) ? $num2 : $num1;
        printf "%.4f ", $item/$num;
    }
    print "\n";
}

Вывод :

0.0000 0.0000 0.8125 1.0769 
0.0000 0.0000 0.8125 1.0769 
0.8125 0.8125 0.0000 0.6875 
1.0769 1.0769 0.6875 0.0000