如何在perl中找到水平绝对值
How to find the horizontal absolute value in perl
我有这个代码
if (@row1) {
die "Bad format!" if @row1 != @row2;
my @new = map { abs ($row2[$_] - $row1[$_]) } 0..$#row2;
这是 row2 -row1 的绝对值。
我尝试代替 abs (row2-row1) 来查找所有行的每一行的同一行的元素 2 - 元素 1 的绝对值,以连续上层代码。我的目标是获取 abs(row2 -row1) --> 从新值 --> second element - first element of the same line for all the lines.
1 2 3 4
1 4 3 4
1 5 2 3
成为
0 2 0 0
0 1 1 1
这已经完成,然后有最终输出
2 2 0
1 0 1
所以我将上面的代码编辑为:
for ($i=1,$i++,$i>$row){
my @new1 = map { abs ($row1[+$i] - $row1[+$i]) } 0..$#row1;
say join " ", @new1;}
但我得到了 "Use of uninitialized value $i in addition"。我还将 $i 替换为 "my$i" 以及 "i" 并出现相同的错误。有人可以向我解释为什么我正在尝试的是错误的吗?
my @rows = (
[ 1, 2, 3, 4 ],
[ 1, 4, 3, 4 ],
[ 1, 5, 2, 3 ],
);
my $num_cols = @{ $rows[0] };
for my $r (1..$#rows) {
die "Bad format!" if @{ $rows[$r] } != $num_cols;
my @diffs = map { abs($rows[$r-1][$_] - $rows[$r][$_]) } 0..$num_cols-1;
my @diff_diffs = map { abs($diffs[$_-1] - $diffs[$_]) } 1..$num_cols-1;
say "@diff_diffs";
}
问题的许多可能解决方案之一
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $debug = 0; # debug flag
my $flag = 1;
my @current;
my @previous;
my @final;
say "First stage";
while( <DATA> ) {
@current = split ' ';
if( $flag ) {
@previous = @current;
$flag = 0;
next;
}
if( $#current != $#previous ) {
say "Ops, lines have different number of elements";
say "Previous: " . join ' ', @previous;
say "Current: " . join ' ', @current;
} else {
my @data = map { abs($current[$_]-$previous[$_]) } 0..$#current;
say join ' ', @data;
push @final, \@data;
}
@previous = @current;
}
print Dumper(\@final) if $debug;
say "Second stage";
foreach my $row (@final) {
my @data = map { abs(@{$row}[$_]-@{$row}[$_+1]) } 0..$#{$row}-1;
say join ' ', @data;
}
__DATA__
1 2 3 4
1 4 3 4
1 5 2 3
输出
First stage
0 2 0 0
0 1 1 1
Second stage
2 2 0
1 0 0
OP的问题不是很清楚他想用这些数据做什么。
我的理解是他想递归地应用vertical和horizontalabs diff .
为了简化处理代码,实现了两个子例程abs_vdiff和abs_hdiff。
#!/usr/bin/perl
#
# USAGE:
# prog.pl
#
# Description:
# Demonstration code for Whosebug Q59945359
#
# Whosebug:
# Question 59945359
#
# Author:
# Polar Bear
#
# Date: Tue Jan 28 13:35:00 PST 2020
#
use strict;
use warnings;
use feature 'say';
my $array = read_array();
my $vdiff = abs_vdiff($array);
my $hdiff = abs_hdiff($vdiff);
say "Read array";
show($array);
say "ABS vertical diff";
show($vdiff);
say "ABS horizontal diff";
show($hdiff);
say "We done";
sub read_array {
my @data;
while( <DATA> ) {
my @row = split ' ';
push @data, \@row;
}
return \@data;
}
sub abs_vdiff {
my $array = shift;
my @result;
foreach my $i ( 1..$#{$array} ) {
my @data = map { abs(@{@{$array}[$i]}[$_]-@{@{$array}[$i-1]}[$_]) } 0..$#{@{$array}[$i]};
push @result, \@data;
}
return \@result;
}
sub abs_hdiff {
my $array = shift;
my @data;
foreach my $row (@{$array}) {
my @row = map { abs(@{$row}[$_]-@{$row}[$_+1]) } 0..$#{$row}-1;
push @data, \@row;
}
return \@data;
}
sub show {
my $array = shift;
foreach my $row ( @{$array} ) {
say join ' ', @{$row};
}
}
__DATA__
1 2 3 4
1 4 3 4
1 5 2 3
输出
Read array
1 2 3 4
1 4 3 4
1 5 2 3
ABS vertical diff
0 2 0 0
0 1 1 1
ABS horizontal diff
2 2 0
1 0 0
We done
我有这个代码
if (@row1) {
die "Bad format!" if @row1 != @row2;
my @new = map { abs ($row2[$_] - $row1[$_]) } 0..$#row2;
这是 row2 -row1 的绝对值。
我尝试代替 abs (row2-row1) 来查找所有行的每一行的同一行的元素 2 - 元素 1 的绝对值,以连续上层代码。我的目标是获取 abs(row2 -row1) --> 从新值 --> second element - first element of the same line for all the lines.
1 2 3 4
1 4 3 4
1 5 2 3
成为
0 2 0 0
0 1 1 1
这已经完成,然后有最终输出
2 2 0
1 0 1
所以我将上面的代码编辑为:
for ($i=1,$i++,$i>$row){
my @new1 = map { abs ($row1[+$i] - $row1[+$i]) } 0..$#row1;
say join " ", @new1;}
但我得到了 "Use of uninitialized value $i in addition"。我还将 $i 替换为 "my$i" 以及 "i" 并出现相同的错误。有人可以向我解释为什么我正在尝试的是错误的吗?
my @rows = (
[ 1, 2, 3, 4 ],
[ 1, 4, 3, 4 ],
[ 1, 5, 2, 3 ],
);
my $num_cols = @{ $rows[0] };
for my $r (1..$#rows) {
die "Bad format!" if @{ $rows[$r] } != $num_cols;
my @diffs = map { abs($rows[$r-1][$_] - $rows[$r][$_]) } 0..$num_cols-1;
my @diff_diffs = map { abs($diffs[$_-1] - $diffs[$_]) } 1..$num_cols-1;
say "@diff_diffs";
}
问题的许多可能解决方案之一
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $debug = 0; # debug flag
my $flag = 1;
my @current;
my @previous;
my @final;
say "First stage";
while( <DATA> ) {
@current = split ' ';
if( $flag ) {
@previous = @current;
$flag = 0;
next;
}
if( $#current != $#previous ) {
say "Ops, lines have different number of elements";
say "Previous: " . join ' ', @previous;
say "Current: " . join ' ', @current;
} else {
my @data = map { abs($current[$_]-$previous[$_]) } 0..$#current;
say join ' ', @data;
push @final, \@data;
}
@previous = @current;
}
print Dumper(\@final) if $debug;
say "Second stage";
foreach my $row (@final) {
my @data = map { abs(@{$row}[$_]-@{$row}[$_+1]) } 0..$#{$row}-1;
say join ' ', @data;
}
__DATA__
1 2 3 4
1 4 3 4
1 5 2 3
输出
First stage
0 2 0 0
0 1 1 1
Second stage
2 2 0
1 0 0
OP的问题不是很清楚他想用这些数据做什么。
我的理解是他想递归地应用vertical和horizontalabs diff .
为了简化处理代码,实现了两个子例程abs_vdiff和abs_hdiff。
#!/usr/bin/perl
#
# USAGE:
# prog.pl
#
# Description:
# Demonstration code for Whosebug Q59945359
#
# Whosebug:
# Question 59945359
#
# Author:
# Polar Bear
#
# Date: Tue Jan 28 13:35:00 PST 2020
#
use strict;
use warnings;
use feature 'say';
my $array = read_array();
my $vdiff = abs_vdiff($array);
my $hdiff = abs_hdiff($vdiff);
say "Read array";
show($array);
say "ABS vertical diff";
show($vdiff);
say "ABS horizontal diff";
show($hdiff);
say "We done";
sub read_array {
my @data;
while( <DATA> ) {
my @row = split ' ';
push @data, \@row;
}
return \@data;
}
sub abs_vdiff {
my $array = shift;
my @result;
foreach my $i ( 1..$#{$array} ) {
my @data = map { abs(@{@{$array}[$i]}[$_]-@{@{$array}[$i-1]}[$_]) } 0..$#{@{$array}[$i]};
push @result, \@data;
}
return \@result;
}
sub abs_hdiff {
my $array = shift;
my @data;
foreach my $row (@{$array}) {
my @row = map { abs(@{$row}[$_]-@{$row}[$_+1]) } 0..$#{$row}-1;
push @data, \@row;
}
return \@data;
}
sub show {
my $array = shift;
foreach my $row ( @{$array} ) {
say join ' ', @{$row};
}
}
__DATA__
1 2 3 4
1 4 3 4
1 5 2 3
输出
Read array
1 2 3 4
1 4 3 4
1 5 2 3
ABS vertical diff
0 2 0 0
0 1 1 1
ABS horizontal diff
2 2 0
1 0 0
We done