求解Perl中两个等长字符串的快速方法

nev*_*int 5 unix linux string perl

给出这样的字符串对.

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

   # Note the string can be longer than this.
Run Code Online (Sandbox Code Playgroud)

我想在$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
Run Code Online (Sandbox Code Playgroud)

我可以轻松实现这一目标substr().但它非常缓慢.通常我需要比较数百万这样的对.

有没有快速的方法来实现这一目标?

yst*_*sth 22

Stringwise ^是你的朋友:

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";
}
Run Code Online (Sandbox Code Playgroud)

说明:

^(异或)运算,对字符串中使用时,返回一个排他性的或在每个字符的数字值的每个比特的结果所组成的字符串.将示例分解为等效代码:

"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)
" " . " "
"  "
Run Code Online (Sandbox Code Playgroud)

这里的有用特性是"\0"当且仅当两个字符串在给定位置具有相同字符时才会出现空字符().因此^可以用于在一个快速操作中有效地比较两个字符串的每个字符,并且可以搜索结果以查找非空字符(指示差异).可以使用标量上下文中的/ g regex标志重复搜索,并使用找到的每个字符差异的位置$-[0],这给出了上次成功匹配开始的偏移量.