如何在Perl中获得数组的最大值

  • 本文关键字:数组 最大值 Perl perl
  • 更新时间 :
  • 英文 :


我有一个输入源,如下所示。我想做的是将每个Layer行上的数值捕获到一个数组中,然后打印出最大值。

输入

MACRO cell_1
size 0.1 by 0.1 ; 
pin a
(....same topology as pin vcc)
END a
pin b
(.....same topology as pin vcc)
END b
Pin vcc
aaaa
bbbb
Port
Layer m2 ;
END
CCC
DDD
Port 
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
END vcc
pin d
(....same topology as pin vcc)
END d
END cell_1
MACRO cell_2
(repeated)
END cell_2 

我的代码:

foreach my $file ( @files ) {   # @files = multiple path  of abc/def/fgh/cell_lef
open( INFILE, "<$file" ) || die "Can not open stdcell_filen";
my @lines = <INFILE>;
close INFILE;
$init = 1;
$delimiter =~ /^$/;      # between each MACRO. haven't utilize this yet
foreach (@lines) {
if ( $init ) {
$path = 1;
$init = 0;
@num  = ();
}
if ( $path ) {
if ( /MACROs+(S+) /) {
$cellname = $1; print "$cellnamen";
}
if ( /SIZEs+(S+)s+(S+)s+(S+)/ ) {
$footprint_x = $1;
$footprint_y = $3;
print "$footprint_x $footprint_yn";
}
if ( /PIN vcc/ .. /END vcc/ ) {
#grab the highest value from layer (m*)
#print "max layer = m*"
}
$init = 1;
}
}
}

预期输出

cell_1
0.1 0.1
m2
cell_2
0.2 0.2
m3

我尝试使用的代码:

if ( /PIN vcc/../END vcc/ ) {
if ( /LAYERs+m(S+) / ) {
push(@num, $1);
print "@num";
}                               
}    

到目前为止,我的代码的问题是,当我打印@num的值时,所有的值都作为字符串(210)连接在一起,而不是单个元素:2 1 0——所以我无法进行排序以获得最大值。

更新:我不确定如何将while集成到我的代码中,因为我使用foreach作为我的主循环

您的代码正在捕获数字,好吧,只是您正在打印整个数组。当您打印数组时,Perl默认的数组元素分隔符是"",也就是说,什么都没有——所以,它看起来像一个字符串,但它是三个(或多个)相邻打印的元素,没有分隔符。

您可以使用while (<>) {以Unix过滤器样式逐行迭代输入。您可以在找到"PIN vcc"时打开"扫描模式"标志,在找到"END vcc"后将其关闭。之后,使用正则表达式搜索图层行,但始终使用"扩展模式"/x,这样您就可以在正则表达式中使用空白。

由于用于切换模式和捕获层数的正则表达式是互斥的,您可以让其他检查在检查成功后进行-只需注意,如果未来的更改导致重叠情况,则需要在其中一个正则表达式成功时执行next

最后,List::Util是一个核心模块,因此,您不妨从中获取max函数;

use v5.12;
use warnings;
use List::Util qw( max );
my @num ;
my $scanning = 0;
while (<>) {
$scanning = 1  if /PIN vcc/ ;
$scanning = 0  if /END vcc/ ;
next unless $scanning ;
push @num, $1  if /Layer s+ m (d+) /x ;
}
say "Max layer number found: ", max(@num) ;

或者只需使用的sort函数即可。

my @values ;
while (<DATA>) 
{    
push (@values , $1) if (/Layers+m(d+)s;/);
}
my ($max) = sort{$b <=> $a} @values ;
print "$maxn";
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m3 ;
END
CCC
DDD
Port 
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END

使用CCD_ 11函数并将第一个结果存储到包含变量CCD_。

my @data = <DATA> ;
my @num ;
foreach (@data) {
push @num, $1 if /Layers+m(S+)/ ;
} 
# home made max() - sorts an anonymous array and prints the last element
print [ sort { $a <=> $b } @num ]->[-1] , "n" ;
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m2 ;
END
CCC
DDD
Port 
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
END vcc

使用map从文件中提取数字。sort的数量,得到最大数量。

#!/usr/bin/perl
use strict;
use warnings;
my $max = (sort{$b <=> $a }map{/Layers+m(d+)/} <DATA>)[0];
print $max,"n";
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m3 ;
END
CCC
DDD
Port 
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END

首先,如果只查找最大值,则不需要存储所有值;第二,循环结束后打印最大值,

my $max = "-inf";
if (/PIN vcc/ .. /END vcc/) {
$max = $1 if /LAYERs+m(S+)/ and $max < $1;
}
# ..
print $max, "n";

最新更新