gpt4 book ai didi

perl - 如何使用 Perl 有效地填充 N x M 网格?

转载 作者:行者123 更新时间:2023-12-02 04:13:18 25 4
gpt4 key购买 nike

我有一个 Perl 脚本,它解析数据文件并写入 5 个填充有 1100 x 1300 网格的输出文件。该脚本有效,但在我看来,它很笨拙并且可能效率不高。该脚本也是继承的代码,我对其进行了一些修改以使其更具可读性。尽管如此,还是一团糟。

目前,脚本读取数据文件(~4Mb)并将其放入数组中。然后它遍历数组解析其内容并将值推送到另一个数组,最后将它们打印到另一个 for 循环中的文件。如果未找到某个点的值,则打印 9999。零是可接受的值。

数据文件有 5 个不同的参数,每个参数都写入自己的文件。

数据示例:

data for the param: 2
5559
// (x,y) count values
280 40 3 0 0 0
280 41 4 0 0 0 0
280 42 5 0 0 0 0 0
281 43 4 0 0 10 10
281 44 4 0 0 10 10
281 45 4 0 0 0 10
281 46 4 0 0 10 0
281 47 4 0 0 10 0
281 48 3 10 10 0
281 49 2 0 0
41 50 3 0 0 0
45 50 3 0 0 0
280 50 2 0 0
40 51 8 0 0 0 0 0 0 0 0
...

data for the param: 3
3356
// (x,y) count values

5559 是当前参数的数据线数。数据线去: x , , 连续 x 值的数量 对于那个特定点,最后是 .
参数之间有一个空行。

正如我之前所说,脚本有效,但我觉得这可以更容易和更有效地完成。我只是不知道怎么做。所以这是一个自我提升的机会。

有什么比数组和 for 循环的复杂组合更好的方法来解决这个问题?

编辑:

应该更清楚这一点,对不起。

输出为 1100 x 1300 网格,填充了从数据文件中读取的值。每个参数被写入不同的文件。数据线上的多个值意味着,该线具有 x(+n)、y 点的数据。

更新:

我测试了解决方案,令我惊讶的是它比原始脚本慢(约 3 秒)。但是,脚本要小约 50%,这使得实际理解脚本的作用变得更加容易。在这种情况下,这比 3 秒的速度增益更重要。

这里是旧脚本中的一些代码。希望你能从中得到基本的想法。为什么更快?
 for my $i (0..$#indata) { # Data file is read to @indata
...
if($indata[$i] =~ /^data for the param:/) {
push @block, $i; # data borders aka. lines, where block starts and ends
}
...
}
# Then handle the data blocks
for my $k (0..4) { # 5 parameters
...
if( $k eq '4') { # Last parameter
$enddata = $#indata;
}
else {
$enddata = $block[$k+1];
}
...
for my $p ($block[$k]..$enddata) { # from current block to next block
...
# Fill data array
for(my $m=0 ; $m<$n ; $m++){
$data[$x][$y] = $values[$m];
}

}
print2file();

}

最佳答案

下面将在一个散列中填充一个稀疏数组。打印时打印9999对于具有未定义值的单元格。我更改了代码以将每一行构建为字符串以减少内存占用。

#!/usr/bin/perl

use strict; use warnings;
use YAML;

use constant GRID_X => 1100 - 1;
use constant GRID_Y => 1300 - 1;

while (my $data = <DATA> ) {
if ( $data =~ /^data for the param: (\d)/ ) {
process_param($1, \*DATA);
}
}

sub process_param {
my ($param, $fh) = @_;
my $lines_to_read = <$fh>;
my $lines_read = 0;

$lines_to_read += 0;

my %data;

while ( my $data = <$fh> ) {
next if $data =~ m{^//};
last unless $data =~ /\S/;
$lines_read += 1;

my ($x, $y, $n, @vals) = split ' ', $data;

for my $i ( 0 .. ($n - 1) ) {
$data{$x + $i}{$y} = 0 + $vals[$i];
}
}
if ( $lines_read != $lines_to_read ) {
warn "read $lines_read lines, expected $lines_to_read\n";
}

# this is where you would open a $param specific output file
# and write out the full matrix, instead of printing to STDOUT
# as I have done. As an improvement, you should probably factor
# this out to another sub.

for my $x (0 .. GRID_X) {
my $row;
for my $y (0 .. GRID_Y) {
my $v = 9999;
if ( exists($data{$x})
and exists($data{$x}{$y})
and defined($data{$x}{$y}) ) {
$v = $data{$x}{$y};
}
$row .= "$v\t";
}
$row =~ s/\t\z/\n/;
print $row;
}

return;
}


__DATA__
data for the param: 2
5559
// (x,y) count values
280 40 3 0 0 0
280 41 4 0 0 0 0
280 42 5 0 0 0 0 0
281 43 4 0 0 10 10
281 44 4 0 0 10 10
281 45 4 0 0 0 10
281 46 4 0 0 10 0
281 47 4 0 0 10 0
281 48 3 10 10 0
281 49 2 0 0
41 50 3 0 0 0
45 50 3 0 0 0
280 50 2 0 0
40 51 8 0 0 0 0 0 0 0 0

关于perl - 如何使用 Perl 有效地填充 N x M 网格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3997280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com