如何在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的问题不是很清楚他想用这些数据做什么。

我的理解是他想递归地应用verticalhorizo​​ntalabs diff .

为了简化处理代码,实现了两个子例程abs_vdiffabs_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