Конечно нет ?? Где твой тест?

ные пары строк, как это.

    my $s1 = "ACTGGA";
    my $s2 = "AGTG-A";

   # Note the string can be longer than this.

Я хотел бы найти положение и характер в$s1 где это отличается от$s2, В этом случае ответ будет:

#String Position 0-based
# First col = Base in S1
# Second col = Base in S2
# Third col = Position in S1 where they differ
C G 1
G - 4

Я могу легко достичь этого сsubstr(), Но это ужасно медленно. Обычно мне нужно сравнить миллионы таких пар.

Есть ли быстрый способ достичь этого?

 dwarring17 янв. 2011 г., 04:08
Классический ответ TimToadyperlmonks.org/?node_id=840593: $ match = ($ first ^ $ second) = ~ tr / \ 0 //;
 ysth17 янв. 2011 г., 04:49
@snoopy: подсчет количества одинаковых символов, а не того, что здесь нужно
 Cameron17 янв. 2011 г., 03:44
Не могли бы вы опубликовать свойsubstr пример с эталоном? Тогда мы могли бы использовать его в качестве основы для сравнения наших потенциальных решений. Кроме того, это не строки Юникода, верно? (Они похожи на генетическую информацию ...) Ввод всегда будет в узком подмножестве символов (т. Е. [ACTG-])?

Ответы на вопрос(4)

и я ответил на вопрос и многое другое. Он будет работать на строках одинаковой длины. Это будет работать, если они не. Я добавил помощь, выбирая обработку просто для удовольствия. Я думал, что кто-то может найти это полезным. Если вы новичок в PERL добавить не знаю. Не добавляйте код в ваш скрипт нижеДАННЫЕ к программе. Веселиться.

./diftxt -h

    usage: diftxt [-v ] string1 string2
                   -v = Verbose 
                  diftxt [-V|--version]
                  diftxt [-h|--help]  "This help!"
Examples:  diftxt test text
           diftxt "This is a test" "this is real"

    Place Holders:  space = "·" , no charater = "ζ"

cat ./diftxt ----------- вырезать ✂ ----------

#!/usr/bin/perl -w

use strict;
use warnings;
use Getopt::Std;
my %options=();
getopts("Vhv", \%options);
my $helptxt='
        usage: diftxt [-v ] string1 string2
                       -v = Verbose 
                      diftxt [-V|--version]
                      diftxt [-h|--help]  "This help!"
    Examples:  diftxt test text
               diftxt "This is a test" "this is real"

        Place Holders:  space = "·" , no charater = "ζ"';
my $Version = "inital-release 1.0 - Quincey Craig 11/21/2012";

print "$helptxt\n\n" if defined $options{h};
print "$Version\n" if defined $options{V};
if (@ARGV == 0 ) {
 if (not defined $options{h}) {usage()};
 exit;
}

my $s1 = "$ARGV[0]";
my $s2 = "$ARGV[1]";
my $mask = $s1 ^ $s2;

#  setup unicode output to STDOUT
binmode DATA, ":utf8";
my $ustring = <DATA>;
binmode STDOUT, ":utf8";

my $_DIFF = '';
my $_CHAR1 = '';
my $_CHAR2 = '';

sub usage
{
        print "\n";
        print "usage: diftxt [-v ] string1 string2\n";
        print "               -v = Verbose \n";
        print "       diftxt [-V|--version]\n";
        print "       diftxt [-h|--help]\n\n";
        exit;
}

sub main
{
 print "\nOrig\tDiff\tPos\n----\t----\t----\n" if defined $options{v};
 while ($mask =~ /[^\0]/g) {
### redirect stderr to allow for test of empty variable with error message from substr   
    open STDERR, '>/dev/null';
    if (substr($s2,$-[0],1) eq "") {$_CHAR2 = "\x{03B6}";close STDERR;} else {$_CHAR2 = substr($s2,$-[0],1)};
    if (substr($s2,$-[0],1) eq " ") {$_CHAR2 = "\x{00B7}"};
      $_CHAR1 = substr($s1,$-[0],1);
    if ($_CHAR1 eq "") {$_CHAR1 = "\x{03B6}"} else {$_CHAR1 = substr($s1,$-[0],1)};
    if ($_CHAR1 eq " ") {$_CHAR1 = "\x{00B7}"};
### Print verbose Data  
   print $_CHAR1, "\t", $_CHAR2, "\t", $+[0], "\n" if defined $options{v};
### Build difference list 
   $_DIFF = "$_DIFF$_CHAR2";
### Build mask 
   substr($s1,"$-[0]",1) = "\x{00B7}";
 } ### end loop

 print "\n" if defined $options{v};
 print "$_DIFF, ";
 print "Mask: \"$s1\"\n";
} ### end main
if ($#ARGV == 1) {main()};
__DATA__

Вещи как$s1 & $s2 или же$s1 ^ $s2 бегать невероятно быстро и работать со строками произвольной длины.

Решение Вопроса

Строгое ^ твой друг:

use strict;
use warnings;
my $s1 = "ACTGGA";
my $s2 = "AGTG-A";

my $mask = $s1 ^ $s2;
while ($mask =~ /[^\0]/g) {
    print substr($s1,$-[0],1), ' ', substr($s2,$-[0],1), ' ', $-[0], "\n";
}

ОБЪЯСНЕНИЕ:

^ (исключающий или) оператор, когда используется в строках, возвращает строку, состоящую из результата монопольного или каждого бита числового значения каждого символа. Разбиваем пример на эквивалентный код:

"AB" ^ "ab"
( "A" ^ "a" ) . ( "B" ^ "b" )
chr( ord("A") ^ ord("a") ) . chr( ord("B") ^ ord("b") )
chr( 65 ^ 97 ) . chr( 66 ^ 98 )
chr(32) . chr(32)
" " . " "
"  "

Полезная особенность этого здесь в том, что нулевой символ ("\0") происходит тогда и только тогда, когда две строки имеют одинаковый символ в заданной позиции. Так^ может использоваться для эффективного сравнения каждого символа двух строк в одной быстрой операции, и в результате можно искать ненулевые символы (что указывает на разницу). Поиск можно повторить, используя флаг регулярного выражения / g в скалярном контексте, а положение каждой разности символов можно найти, используя$-[0], который дает смещение начала последнего успешного матча.

 Brad Mace21 авг. 2012 г., 07:29
Было бы хорошо, если бы вы объяснили, что здесь происходит.
 ysth10 февр. 2013 г., 05:05
спасибо за предлагаемое изменение, чтобы добавить объяснение, @carandraug; Я сделал это несколько иначе.
 Grrrr17 янв. 2011 г., 12:08
Кстати, очень хороший пример использования @ -.

Это самая простая форма, которую вы можете получить

my $s1 = "ACTGGA";
my $s2 = "AGTG-A";

my @s1 = split //,$s1;
my @s2 = split //,$s2;

my $i = 0;
foreach  (@s1) {
    if ($_ ne $s2[$i]) {
        print "$_, $s2[$i] $i\n";
    }
    $i++;
}
 User17 янв. 2011 г., 04:38
Конечно нет ?? Где твой тест?
 bdonlan17 янв. 2011 г., 04:02
Самый простой? Спорные. Самый быстрый? Конечно нет.

Ваш ответ на вопрос