我有一个包含所有可能元素的引用数组,并按自定义顺序排序,而不是字母数字排序。例如,
@ref_array = ('one','two','three','four','five','six');
现在所有输入数组都需要根据引用数组的顺序进行排序。输入数组将始终是引用数组的子集。
@in1 = ('three','one','five'); # Input
@out1 = ('one','three','five'); # Desired Output
@in2 = ('six','five','four','three','two','one'); # Input
@out2 = ('one','two','three','four','five','six') # Desired Output
答案 0 :(得分:10)
my %h = map { $ref_array[$_] => $_ } 0 .. $#ref_array;
my @out1 = @ref_array[ sort { $a <=> $b } @h{@in1} ];
my @out2 = @ref_array[ sort { $a <=> $b } @h{@in2} ];
%h
持有key =&gt;像one
=&gt;这样的val对0
,two
=&gt; 1
等等。
@h{@in1}
是2,0,4
哈希切片,它被排序,数组切片@ref_array[0,2,4]
是one, three, five
答案 1 :(得分:4)
这并不复杂。
第1步,我们需要从您的值到Perl可以排序的某个键的映射,例如数字。我们可以使用自定义归类数组中元素的索引,如:
my %custom_value = map { $ref_array[$_] => $_ } 0 .. $#ref_array;
第2步,我们在您的输入上执行 Schwartzian转换,其中一个上述值为关键:
my @out =
map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map {[ $custom_value{$_} => $_ ]}
@in;
答案 2 :(得分:1)
对于使用小整数键进行排序,基数排序通常是具有O(N)复杂度的更快解决方案:
use Sort::Key::Radix qw(ukeysort);
my @ref = ('one','two','three','four','five','six');
my %ref = map { $ref[$_] => $_ } 0..$#ref;
my @out = ukeysort { $ref{$_} } @in;
或者您也可以使用便宜的O(N)计数排序:
my %ref;
$ref{$_}++ for @in;
no warnings 'uninitialized';
my @out = map { ($_) x $ref{$_} } @ref;
答案 3 :(得分:0)
所有呈现的解决方案都显示O(NlogN)
时间复杂度的排序。有一种方法可以在没有实际排序的情况下进行,因此O(N)
时间复杂度。
sub custom_usort {
my %h;
@h{@_} = ();
grep exists $h{$_}, ('one','two','three','four','five','six');
}
修改强>:
如果输入中有多个值,则有此解决方案:
sub custom_sort {
my %h;
$h{$_}++ for @_;
no warnings 'uninitialized';
map {($_) x $h{$_}} ('one','two','three','four','five','six');
}