我在Perl中将2维数组引用插入到我的堆中。 在构造堆时如何定义'elements'属性以便我可以正确使用我的比较器函数?
my $heap = Heap::Simple->new( order => \&byNumOrStr,
elements => [Array => 0]
);
sub byNumOrStr
{
my ( $a, $b ) = @_;
$b->[0] <=> $a->[0] #0-th element is a number.
||
$a->[1] cmp $b->[1]; #1-st element is a number
}
我一直收到这个错误:
在使用“严格参考”时,不能使用字符串(“2.55”)作为ARRAY参考...(这意味着我可能实际上必须在数字上比较我的“数字字符串”)
答案 0 :(得分:0)
好吧,$a
或$b
可能是作为字符串传入的。尝试在分配后打印出这些变量。
从文档中我可以看到,当你传递elements => [ Array => 0 ]
时,除非数组中的第0项是数组,否则你只会比较第一项中的值阵列的插槽。
[Array => $index]
- 表示元素是数组引用,键为索引$ index。所以现在元素不仅可以是键,还可以是相关数据。
这意味着如果2.55在数组中,如[2.55,...]那么那就是$a
或$b
传入的内容。
elements
条目告诉H::S
您希望如何派生密钥。对于完全通用的方式,它表示您可以通过[Function => $code_ref_for_key]
。你可以这样做:
sub first_two_slots { 我的$ array_ref = shift; return [@ $ array_ref [0,1]]; }
然后按照指定的顺序,它会将该数组传递到您的订单并指定
my $heap = Heap::Simple->new( order => \&byNumOrStr,
elements => [Function => \&first_two_slots]
);
留下原始评论:(与Heap::Simple
调用订单的方式无关。)
如果从byNumOrStr
调用sort
,请不要在其中分配$a
和$b
。这些值由sort
设置。如果@_
中有某些内容可能不是您想要的内容。
答案 1 :(得分:0)
对二维数组进行排序并没有多大意义 - 当您对某些内容进行排序时,会有一个已定义的顺序。有两个排序标准不会使它成为二维列表...你的意思是你有两个元素列表的数据? e.g:
my $element = [ '0', 'string' ];
我认为文档中的示例1(“其中键和值保持独立”)适用于此处 - 您希望对引用进行排序,而不是对值本身进行排序。因此,请尝试使用 elements => "Any"
声明,然后调整排序方法以匹配:
(我错了..它看起来像elements => [Array => 0]
是正确的,因为这些只是简单的旧的arrayrefs被排序。
my $heap = Heap::Simple->new( order => \&byNumOrStr,
elements => [Array => 0],
);
sub byNumOrStr
{
my ( $val1, $val2 ) = @_;
my $result =
$val1->[0] <=> $val2->[0] # the 0th element is a number
||
$val1->[1] cmp $val2->[1]; # the 1st element is a string
# The docs say "this should return a true value if $key1 is smaller than $key2 and a false value otherwise."
return $result == -1;
}
PS。正如Secondary Order in Heap::Simple中所讨论的,Heap :: Simple中的比较函数不希望返回值为-1,0或1,而是真或假。您需要在从函数返回之前转换比较结果。