Perl зацикливается в подпрограммах, чтобы отобразить самую длинную повторяющуюся строку, выбранную для определенного подраздела строки

Мне было интересно, если кто-нибудь знает, как упростить или обобщить этот код. Это дает правильный ответ, однако это применимо только к текущей ситуации. Мой код выглядит следующим образом:

sub longestRepeat{
                                # list of argument @_ is: (sequence, nucleotide)
  my $someSequence = shift(@_);  # shift off the first  argument from the list
  my $whatBP       = shift(@_);  # shift off the second argument from the list
  my $match = 0;



        if ($whatBP eq "AT"){
            if ($someSequence =~ m/(([A][T])\2\2\2\2\2)/g) {

            $match = $1
            }
            return $match;

        }
        if ($whatBP eq "TAGA"){
            if ($someSequence =~ m/(([T][A][G][A])\2\2)/g) {

            $match = $1
            }
            return $match;
        }

        if ($whatBP eq "C"){
            if ($someSequence =~ m/(([C])\2\2)/g) {

            $match = $1
            }
            return $match;
        }
}   

Мой вопрос заключается в том, что во втором операторе if я установил заданное количество повторяющихся паттернов (применимых для строки, которую нам дали). Однако есть ли способ продолжить выполнение цикла while для поиска по \2 (повторение шаблона)? Я имею в виду следующее: если ($someSequence =~ m/(([A][T])\2\2\2\2\2)/g) быть упрощенным и обобщенным с помощью цикла while

1 ответ

Исходя из названия вашей подпрограммы, я предполагаю, что вы хотите найти самую длинную повторяющуюся последовательность в вашей последовательности.

Если так, как насчет следующего:

sub longest_repeat {

    my ( $sequence, $what ) = @_;

    my @matches = $sequence =~ /((?:$what)+)/g ;  # Store all matches

    my $longest;
    foreach my $match ( @matches ) {  # Could also avoid temp variable :
                                      # for my $match ( $sequence =~ /((?:$what)+)/g )

        $longest //= $match ;         # Initialize
                                      #  (could also do `$longest = $match
                                      #                    unless defined $match`)

        $longest = $match if length( $longest ) < length( $match );
    }

    return $longest;  # Note this also handles the case of no matches
}

Если вы можете переварить это, следующая версия достигает по существу той же функциональности с преобразованием Шварца:

sub longest_repeat {

    my ( $sequence, $what ) = @_;                          # Example:
                                                           # --------------------
    my ( $longest ) = map { $_->[0] }                      # 'ATAT' ...
                        sort { $b->[1] <=> $a->[1] }       # ['ATAT',4], ['AT',2]
                          map { [ $_, length($_) ] }       # ['AT',2], ['ATAT',4]
                            $sequence =~ /((?:$what)+)/g ; # ... 'AT', 'ATAT'

    return $longest ;
}

Некоторые могут утверждать, что это расточительно sort потому что это так O(n.log(n)) вместо O(n) но есть разнообразие для тебя.

Другие вопросы по тегам