显式包名称和屏蔽同一语句中的早期声明
Explicit package name and masking earlier declarations in the same statement
我尝试编写了以下算法的 perl 版本
这是我的代码:
#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;
my $s1 = 'GATTACCA';
my $s2 = 'AGTGGGCGGGGAGAGAGAGAGAGG';
my $dist = levdist($s1, $s2);
sub levdist
{
my ( $seq1, $seq2 ) = (@_)[0,1];
my $l1 = length($s1);
my $l2 = length($s2);
my @s1 = split '', $seq1;
my @s2 = split '', $seq2;
for (my $i = 0; $i <= $l1; $i++) {
my $distances->[$i]->[0] = $i;
}
for (my $j = 0; $j <= $l2; $j++) {
my $distances->[0]->[$j] = $j;
}
for (my $i = 1; $i <= $l1; $i++) {
for (my $j = 1; $j <= $l2; $j++) {
if ( $s1[$i-1] eq $s2[$j-1] ) {
my $cost = 0;
} else {
my $cost = 1;
}
my $distances->[$i]->[$j] = minimum($distances->[$i-1]->[$j-1] + my $cost,
$distances->[$i]->[$j-1]+1,
$distances->[$i-1]->[$j]+ 1 )
}
}
my $min_distance = my $distances->[$l1]->[$l2];
for (my $i = 0; $i <= $l1; $i++) { my $min_distance = minimum($min_distance, my $distances->[$i]->[$l2]);
}
for (my $j = 0; $j <= $l2; $j++ ) {
my $min_distance = minimum($min_distance, my $distances->[$l1]->[$j]);
}
return $min_distance;
}
sub minimum
{
my $min = shift @_;
foreach ( @_ ) {
if ( $_ < $min ) {
$min = $_;
}
}
return $min;
}
这会引发以下错误:
Global symbol "$distances" requires explicit package name at ./levenshtein.pl line 33.
Global symbol "$distances" requires explicit package name at ./levenshtein.pl line 34.
Global symbol "$distances" requires explicit package name at ./levenshtein.pl line 35.
当我将代码更改为如下所示时:
my $distances->[$i]->[$j] = minimum(my $distances->[$i-1]->[$j-1] + my $cost,
my $distances->[$i]->[$j-1]+1,
my $distances->[$i-1]->[$j]+ 1
我收到以下一组错误:
"my" variable $distances masks earlier declaration in same statement at
./levenshtein.pl line 33 (#1)
(W misc) A "my", "our" or "state" variable has been redeclared in the
current scope or statement, effectively eliminating all access to the
previous instance. This is almost always a typographical error. Note
that the earlier variable will still exist until the end of the scope
or until all closure references to it are destroyed.
"my" variable $distances masks earlier declaration in same statement at
./levenshtein.pl line 34 (#1)
"my" variable $distances masks earlier declaration in same statement at
./levenshtein.pl line 35 (#1)
我感觉自己陷入了第 22 条军规。如果我声明变量或不声明变量,我都会收到错误消息。任何见解将不胜感激。
谢谢,
使用 my
在适当的范围内声明一个变量一次。当它超出范围时,它将被清理。
使用库函数以免重新发明轮子。 List::More
您还应该使用更好的变量名。 $i,$l1,$i1
它们很难阅读,但容易引入错误。
使用范围运算符会更好,所以不要写
for (my $i = 0; $i <= $l1; $i++) {
你可以使用 for my $i ( 0 .. $l1 ) {
但是你可能需要 (0 .. $li-1)
而不是 (0 .. $li)
因为 perl 数组默认是 0-based,所以你可能是引入错误。
我建议您编写一个测试文件来验证您的算法的结果。
这是一个有效的(compiling/running,不一定正确)版本:
#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;
use List::Util qw( min max );
my $s1 = 'GATTACCA';
my $s2 = 'AGTGGGCGGGGAGAGAGAGAGAGG';
my $dist = levdist($s1, $s2);
print "Distance between '$s1' and '$s2' is $dist\n";
sub levdist {
my ( $seq1, $seq2 ) = (@_);
my $l1 = length($s1);
my $l2 = length($s2);
my @s1 = split '', $seq1;
my @s2 = split '', $seq2;
my $distances;
for (my $i = 0; $i <= $l1; $i++) {
$distances->[$i]->[0] = $i;
}
for (my $j = 0; $j <= $l2; $j++) {
$distances->[0]->[$j] = $j;
}
for (my $i = 1; $i <= $l1; $i++) {
for (my $j = 1; $j <= $l2; $j++) {
my $cost;
if ( $s1[$i-1] eq $s2[$j-1] ) {
$cost = 0;
} else {
$cost = 1;
}
$distances->[$i]->[$j] = min($distances->[$i-1]->[$j-1] + $cost,
$distances->[$i]->[$j-1]+1,
$distances->[$i-1]->[$j]+ 1 )
}
}
my $min_distance = $distances->[$l1]->[$l2];
for (my $i = 0; $i <= $l1; $i++) {
$min_distance = min($min_distance, $distances->[$i]->[$l2]);
}
for (my $j = 0; $j <= $l2; $j++ ) {
$min_distance = min($min_distance, $distances->[$l1]->[$j]);
}
return $min_distance;
}
输出
Distance between 'GATTACCA' and 'AGTGGGCGGGGAGAGAGAGAGAGG' is 6
读一读:
我尝试编写了以下算法的 perl 版本
这是我的代码:
#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;
my $s1 = 'GATTACCA';
my $s2 = 'AGTGGGCGGGGAGAGAGAGAGAGG';
my $dist = levdist($s1, $s2);
sub levdist
{
my ( $seq1, $seq2 ) = (@_)[0,1];
my $l1 = length($s1);
my $l2 = length($s2);
my @s1 = split '', $seq1;
my @s2 = split '', $seq2;
for (my $i = 0; $i <= $l1; $i++) {
my $distances->[$i]->[0] = $i;
}
for (my $j = 0; $j <= $l2; $j++) {
my $distances->[0]->[$j] = $j;
}
for (my $i = 1; $i <= $l1; $i++) {
for (my $j = 1; $j <= $l2; $j++) {
if ( $s1[$i-1] eq $s2[$j-1] ) {
my $cost = 0;
} else {
my $cost = 1;
}
my $distances->[$i]->[$j] = minimum($distances->[$i-1]->[$j-1] + my $cost,
$distances->[$i]->[$j-1]+1,
$distances->[$i-1]->[$j]+ 1 )
}
}
my $min_distance = my $distances->[$l1]->[$l2];
for (my $i = 0; $i <= $l1; $i++) { my $min_distance = minimum($min_distance, my $distances->[$i]->[$l2]);
}
for (my $j = 0; $j <= $l2; $j++ ) {
my $min_distance = minimum($min_distance, my $distances->[$l1]->[$j]);
}
return $min_distance;
}
sub minimum
{
my $min = shift @_;
foreach ( @_ ) {
if ( $_ < $min ) {
$min = $_;
}
}
return $min;
}
这会引发以下错误:
Global symbol "$distances" requires explicit package name at ./levenshtein.pl line 33.
Global symbol "$distances" requires explicit package name at ./levenshtein.pl line 34.
Global symbol "$distances" requires explicit package name at ./levenshtein.pl line 35.
当我将代码更改为如下所示时:
my $distances->[$i]->[$j] = minimum(my $distances->[$i-1]->[$j-1] + my $cost,
my $distances->[$i]->[$j-1]+1,
my $distances->[$i-1]->[$j]+ 1
我收到以下一组错误:
"my" variable $distances masks earlier declaration in same statement at
./levenshtein.pl line 33 (#1)
(W misc) A "my", "our" or "state" variable has been redeclared in the
current scope or statement, effectively eliminating all access to the
previous instance. This is almost always a typographical error. Note
that the earlier variable will still exist until the end of the scope
or until all closure references to it are destroyed.
"my" variable $distances masks earlier declaration in same statement at
./levenshtein.pl line 34 (#1)
"my" variable $distances masks earlier declaration in same statement at
./levenshtein.pl line 35 (#1)
我感觉自己陷入了第 22 条军规。如果我声明变量或不声明变量,我都会收到错误消息。任何见解将不胜感激。 谢谢,
使用
my
在适当的范围内声明一个变量一次。当它超出范围时,它将被清理。使用库函数以免重新发明轮子。
List::More
您还应该使用更好的变量名。
$i,$l1,$i1
它们很难阅读,但容易引入错误。使用范围运算符会更好,所以不要写
for (my $i = 0; $i <= $l1; $i++) {
你可以使用for my $i ( 0 .. $l1 ) {
但是你可能需要
(0 .. $li-1)
而不是(0 .. $li)
因为 perl 数组默认是 0-based,所以你可能是引入错误。我建议您编写一个测试文件来验证您的算法的结果。
这是一个有效的(compiling/running,不一定正确)版本:
#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;
use List::Util qw( min max );
my $s1 = 'GATTACCA';
my $s2 = 'AGTGGGCGGGGAGAGAGAGAGAGG';
my $dist = levdist($s1, $s2);
print "Distance between '$s1' and '$s2' is $dist\n";
sub levdist {
my ( $seq1, $seq2 ) = (@_);
my $l1 = length($s1);
my $l2 = length($s2);
my @s1 = split '', $seq1;
my @s2 = split '', $seq2;
my $distances;
for (my $i = 0; $i <= $l1; $i++) {
$distances->[$i]->[0] = $i;
}
for (my $j = 0; $j <= $l2; $j++) {
$distances->[0]->[$j] = $j;
}
for (my $i = 1; $i <= $l1; $i++) {
for (my $j = 1; $j <= $l2; $j++) {
my $cost;
if ( $s1[$i-1] eq $s2[$j-1] ) {
$cost = 0;
} else {
$cost = 1;
}
$distances->[$i]->[$j] = min($distances->[$i-1]->[$j-1] + $cost,
$distances->[$i]->[$j-1]+1,
$distances->[$i-1]->[$j]+ 1 )
}
}
my $min_distance = $distances->[$l1]->[$l2];
for (my $i = 0; $i <= $l1; $i++) {
$min_distance = min($min_distance, $distances->[$i]->[$l2]);
}
for (my $j = 0; $j <= $l2; $j++ ) {
$min_distance = min($min_distance, $distances->[$l1]->[$j]);
}
return $min_distance;
}
输出
Distance between 'GATTACCA' and 'AGTGGGCGGGGAGAGAGAGAGAGG' is 6
读一读: