0

我没有意识到这个看起来很简单的问题会如此难以破解。

无论如何,我有一个包含 3 个浮点数的数组。我需要找出所有三个中最小的(在这种情况下是三个中最小的,我的实际代码将包含超过 3 个浮点数)

这是我的代码:

#!/usr/bin/perl -w
use strict;
use List::Util qw /min/;
my @array = ("2.7.4", "2.7.0", "2.7.0");
print min(@array);

输出:

Argument "2.7.4" isn't numeric in subroutine entry at min.pl line 6.
Argument "2.7.0" isn't numeric in subroutine entry at min.pl line 6.
Argument "2.7.0" isn't numeric in subroutine entry at min.pl line 6.
2.7.4

所以它抛出了很多错误以及输出数是错误的。

我拍摄的另一张照片是对数组 ( sort {$a <=> $b} @array) 进行排序,然后找到最小的一个,但它再次未能完成这项工作。

我可以逐个进行比较,但如果数组中的元素数量超过三个,代码看起来会很糟糕。

你能帮忙吗。

谢谢。

4

3 回答 3

7

这些不是浮点数,因为它们有不止一个小数分隔符!它们看起来像版本号。你想要Sort::Naturallyversion

于 2013-04-17T09:12:49.283 回答
2

你可以使用版本

#!/usr/bin/perl
use strict;
use warnings;
use version 0.77 (); # disable importing qv

use List::Util qw'min';
my @array = map{
  version->parse($_)
} qw' 2.7.4  2.7.0  2.7.0 ';

print min(@array), "\n";

或者您可以将其转换为vstring,并使用字符串比较(不推荐)。

要么手动

#!/usr/bin/perl
use strict;
use warnings;

sub to_vstring{
  # join '', map chr, split /[.]/, shift
  pack 'U*', split /[.]/, shift;
}

sub from_vstring{
  # join '.', map ord, split //, shift
  join '.', unpack 'U*', shift;
}

use List::Util qw'minstr'; # not min
my @array = map{
  to_vstring($_)
} qw' 2.7.4  2.7.0  2.7.0 ';

print from_vstring( minstr(@array) ), "\n";

或使用字符串eval

sub to_vstring{
  my $c = shift;
  die "invalid vstring '$c'" unless $c =~ /^v?[0-9]+(?:[.][0-9]+)*$/;
  $c = 'v'.$c unless substr($c,0,1) eq 'v';
  eval $c;
}

sub from_vstring{
  my $c = shift;
  die "not a vstring '$c'" unless ref(\$c) eq 'VSTRING';
  # join '.', map ord, split //, shift
  join '.', unpack 'U*', shift;
}

如果您打算走这条路线,您可能需要随身携带原始字符串。

my @array = map{
  [ to_vstring($_), $_ ]
} qw' 2.7.4  2.7.0  2.7.0 ';

my $min_pair = sort {$a->[0] cmp $b->{0]} @array;

my $min = $min_pair->[1];

print $min, "\n"
于 2013-04-17T20:58:44.707 回答
1

您收到的消息不是错误,而是警告。你得到这些是因为你用-w开关启用了它们,我建议你用 替换它use warnings;,因为当你用-w.

无法对列表进行排序的原因min是那些不是浮点数,而是字符串。在数字上下文中比较字符串时,perl 提取它认为是数字的内容。"2.7.4"在is2.7和 for的情况下"2.7.0"也是2.7

如果您的格式没有改变,字符串比较(如其他答案所建议的)可能会起作用。但是字符串比较看起来"12"比,"9"因为它从左到右比较字符串的字符,并通过第一对不同的字符来决定哪个字符串更大或更小。

如果您要比较的那些数字类似于版本号,则该数字"2.10.1"可能会出现,并且通过字符串比较将被视为小于"2.7.0". 一种解决方法是split将字符串分成三个单独的数字并分别比较它们(如何做到这一点留给读者作为练习)。

于 2013-04-17T09:17:37.007 回答