my ($len, $longest) =0;
length > $len and ($longest, $len)=($_, length) for @matches;
@matches
存储一些子串。此代码捕获@matches
中最长的子字符串,然后将其存储在$longest
中。
源代码:
#!usr/bin/perl
use strict;
use Data::Dumper;
my $needle = "axibidm";
my $haystack = "axididm";
my @matches;
for my $start (0..length $needle) {
for my $len (1 .. ((length $needle)-$start)) {
my $substr = substr($needle, $start, $len);
push @matches, $haystack =~ m[($substr)]g;
print "$substr\t";
print "@matches\t\n";
}
}
my ($len, $longest) = 0;
length > $len and ($longest, $len) = ($_, length) for @matches;
print "The longest common substring between\n", $needle, "\nand\n", $haystack, "\nis '$longest'\n";
答案 0 :(得分:3)
有人太聪明了,或者他们打错了。或两者。可能两者都有。
有些事情正在发生,而这些代码并没有做它看起来正在做的事情。这不会将两个变量初始化为零。
my ($len, $longest) = 0;
这是一种欺骗性的写作方式。
my $len = 0;
my $longest;
for $matches
是愚蠢的,只有一件事要迭代,为什么要使用循环呢?这个习惯用法偶尔用于将值放入$_
并在各种默认构造中使用它,但这在这里用得不多。
接下来,以下是写do this if that
的一种非常折磨的方式。它编写的方式使它成为一个单独的表达式,它将在for循环语句修饰符中起作用。
length > $len and ($longest, $len)=($_, length)
这样的写得好得多。
if( length > $len ) {
$longest = $_;
$len = length;
}
扩展它,并删除无用的for循环,我们得到......
my $len = 0;
my $longest;
if( length $match > $len ) {
$longest = $match;
$len = length $match;
}
另一个选项是$matches
是一个数组引用,它们的意思是for @$matches
。 for $matches
仍然可以"工作"但它总是返回21的长度,因为数组引用字符串为ARRAY(0x7fc07c800468)
。
答案 1 :(得分:1)
这看起来几乎是故意混淆的。这是对同一逻辑的更详细的表达。
my $len = 0;
my $longest;
foreach my $match (@matches) {
if (length($match) > $len) {
$longest = $match;
$len = length($match);
}
}
所以让我们进行比较。
my ($len, $longest) = 0;
这声明了两个词法(my
)变量$len
和$longest
,并将第一个($len
)设置为0,将$longest
保留为其默认值为undef
。
这个结构:
(code goes here) for @matches;
与此相同:
for (@matches) {
(code goes here)
}
所以我们迭代@matches
数组并为每个元素运行一次代码。在代码体内,特殊变量$_
将保存当前元素。
length > $len and ($longest, $len) = ($_, length);
首先,(expression) and (code)
是撰写if ( (expression) ) { (code) }
的简写方式。它的工作原理是因为在Perl中,and
以短路方式从左到右进行评估。也就是说,如果左侧表达式为假,则Perl不会对右侧进行评估,因为它的值无关紧要; false and
任何内容都是false
。
如果在没有参数的情况下调用length
,则表示length($_)
,这是正在检查的当前元素@matches
的长度。
($var1, $var2) = ($val1, $val2)
是并行分配,可将$var1
设置为$val1
,将$var2
设置为$val2
。
答案 2 :(得分:1)
EXPR for LIST;
与
大致相同for (LIST) { EXPR; }
EXPR1 and EXPR2;
与
大致相同if (EXPR1) { EXPR2; }
(这不是普遍接受的做法,除非EXPR2
是流量控制表达式(next
,die
等)。)
length
默认使用$_
作为参数(length($_)
)。
( $x, $y ) = ( EXPR1, EXPR2 )
与
大致相同$x = EXPR1;
$y = EXPR2;
(一个值得注意的区别是,您可以($x,$y)=($y,$x)
交换值,但这里使用的是。)
(当两个标量赋值执行时使用列表赋值也不是普遍接受的做法。)
更常规的编写代码的方法是:
my $len = 0;
my $longest;
for (@matches) {
if (length($_) > $len) {
$longest = $_;
$len = length($_);
}
}