In Mathe, was Sie sich beziehen, sind argmax und argmin genannt. Sie können ihre Funktionalität auf verschiedene Arten erhalten.
Zuerst, eine Liste von Werten gegeben, können Sie ihr Maximum und Minimum finden, und wählen Sie dann die Indizes, die den Elementen der Liste mit den maximalen bzw. minimalen Werten entsprechen. Dies ist in der folgenden Funktion using_only_max_min
implementiert. Beachten Sie, dass diese Methode zwei Übergänge über das Array für jedes Extremum durchführt: Einmal, um das Extremum zu finden, und ein anderes Mal, um die entsprechenden Indizes zu finden.
Oder, bei einer Liste von Werten, können Sie die Indizes finden, die den Extrema in der Liste entsprechen, und dann den entsprechenden Wert für jeden von ihnen auswählen, um den Wert des Extremums zu erhalten. Dies ist in der folgenden using_by_functions
Routine implementiert.
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use List::AllUtils qw(max min max_by min_by);
my @n = (1, 3, 5, 8, 8, 3, 2, 4, 4, 6);
print Dumper using_only_max_min(\@n);
print Dumper using_by_functions(\@n);
sub using_only_max_min {
my $n = shift;
my $max = max @$n;
my @argmax = grep $n->[$_] == $max, 0 .. $#$n;
my $min = min @$n;
my @argmin = grep $n->[$_] == $min, 0 .. $#$n;
return {
max => $max,
argmax => \@argmax,
min => $min,
argmin => \@argmin,
};
}
sub using_by_functions {
my $n = shift;
my @argmax = max_by { $n->[$_] } 0 .. $#$n;
my $max = $n->[$argmax[0]];
my @argmin = min_by { $n->[$_] } 0 .. $#$n;
my $min = $n->[$argmin[0]];
return {
max => $max,
argmax => \@argmax,
min => $min,
argmin => \@argmin,
};
}
Ausgang:
$VAR1 = {
'argmin' => [
0
],
'max' => 8,
'min' => 1,
'argmax' => [
3,
4
]
};
$VAR1 = {
'argmax' => [
3,
4
],
'min' => 1,
'max' => 8,
'argmin' => [
0
]
};
Sie können dies auch tun, ohne Bibliotheken und finden die beiden Extrema in einem Rutsch. Die folgende Funktion gibt eine Hash-Referenz zurück, die zwei Einträge enthält: max
und min
. Jede dieser Stelle auf eine Liste, deren ersten Wert ist der Wert des Extremums, und der zweite Wert ist die Liste von Indizes auf das Extremum entsprechen:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my @n = (1, 3, 5, 8, 8, 3, 2, 4, 4, 6);
print Dumper find_extrema(\@n, sub { $_[0] <=> $_[1]});
sub find_extrema {
my ($n, $cmp) = @_;
my ($max, $min) = ([$n->[0], [0]], [$n->[0], [0]]);
for my $i (1 .. $#$n) {
my $v = $n->[$i];
my $r = $cmp->($v, $max->[0]);
if ($r >= 0) {
$r ? $max = [$v, [$i]] : push @{ $max->[-1] }, $i;
next;
}
my $s = $cmp->($v, $min->[0]);
if ($s <= 0) {
$s ? $min = [$v, [$i]] : push @{ $min->[-1] }, $i;
}
}
return {
max => $max,
min => $min,
};
}
Output:
$VAR1 = {
'min' => [
1,
[
0
]
],
'max' => [
8,
[
3,
4
]
]
};
35 Punkte gehen und es zeigt bereits 100k. Du hast bald eine Tasse auf deinem Weg! :) – simbabque
Ich hatte gehofft, diese Funktion wiederverwenden zu können, daher habe ich es in ein Sub eingefügt. Ich werde zuerst über% hash lesen und zurückkommen. Vielen Dank für Ihren Vorschlag bis jetzt! – AlexAMP
@simbabque: Ist das immer noch eine Sache? – Borodin