subir soluciones soban sobada señoras que para mujeres matriz jovenes imagenes imagen curar como caida acomodar arrays perl sorting

arrays - soban - matriz caida soluciones



¿Ordenar Perl matriz en su lugar? (3)

Tengo una referencia a una matriz (llamada $intervals ) y me gustaría ordenar los valores en esta matriz. Es posible que haya una gran cantidad de valores en la matriz, por lo que preferiría no copiar los valores. Mi enfoque actual es este.

sub by_position { $a->start <=> $b->start || $a->end <=> $b->end } my @sorted_intervals = sort by_position (@$intervals);

Sin embargo, si entiendo a Perl correctamente, esto copiará todos los valores de la matriz. ¿Está bien? Si es así, ¿hay alguna manera de que pueda hacer una especie de matriz in situ (usando una referencia a esa matriz)?


Desde Perl 5.8.4, la ordenación in situ @a = sort @a está optimizada. Vea los enlaces a continuación para más detalles:

Mejoras de rendimiento en perl584delta

http://perl5.git.perl.org/perl.git/commit/fe1bc4cf71e7b04d33e679798964a090d9fa7b46?f=pp_sort.c

+ /* optimiser converts "@a = sort @a" to "sort /@a"; + * in case of tied @a, pessimise: push (@a) onto stack, then assign + * result back to @a at the end of this function */

Así que deberías poder escribir:

@$intervals = sort by_position @$intervals

Y en Perl posterior a 5.8.3, verá un uso reducido de la memoria (y la preservación del aliasing para las raras ocasiones en que sea importante).


El segundo ejemplo creará una nueva referencia: $x = [ qw( acb ) ]; say $x; @$x = sort @$x; say $x; $x = [sort @$x]; say $x $x = [ qw( acb ) ]; say $x; @$x = sort @$x; say $x; $x = [sort @$x]; say $x $x = [ qw( acb ) ]; say $x; @$x = sort @$x; say $x; $x = [sort @$x]; say $x . El primer ejemplo hace lo que deseas. ref .


Perl permite que las matrices se @arr = sort @arr en el lugar con el idioma @arr = sort @arr . Contrariamente al comportamiento normal del operador de asignación, no se harán copias en este caso. Sin embargo, esta optimización está limitada a las variables de matriz normales; no funcionará con referencias de matriz:

Veamos debajo del capó utilizando la opción -MO=Concise . Primero, hacemos una clasificación normal en el lugar para ver qué esperaríamos:

$ perl -E''say $^V'' v5.18.2 $ perl -MO=Concise -e''my @arr; @arr = sort @arr'' 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 3 <0> padav[@arr:1,2] vM/LVINTRO ->4 4 <;> nextstate(main 2 -e:1) v:{ ->5 - <1> ex-aassign vKS/64 ->8 - <1> ex-list lK ->- 5 <0> pushmark s ->6 7 <@> sort lK/INPLACE ->8 6 <0> padrange[@arr:1,2] l/1 ->7 - <0> padav[@arr:1,2] lRM* ->7 - <1> ex-list lK ->- - <0> ex-pushmark s ->- - <0> ex-padav lRM* ->- -e syntax OK

Interesante: <@> sort lK/INPLACE ->8 , que parece <@> sort lK/INPLACE ->8 en su lugar. Ahora hagamos lo mismo con las referencias:

$ perl -MO=Concise -e''my $ref; @$ref = sort @$ref'' e <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 3 <0> padsv[$ref:1,2] vM/LVINTRO ->4 4 <;> nextstate(main 2 -e:1) v:{ ->5 d <2> aassign[t4] vKS/COMMON ->e - <1> ex-list lK ->a 5 <0> pushmark s ->6 9 <@> sort lK ->a 6 <0> pushmark s ->7 8 <1> rv2av[t3] lK/1 ->9 7 <0> padsv[$ref:1,2] s ->8 - <1> ex-list lK ->d a <0> pushmark s ->b c <1> rv2av[t2] lKRM*/1 ->d b <0> padsv[$ref:1,2] sM/DREFAV ->c -e syntax OK

No veo una bandera in situ en <@> sort lK ->a . Por lo tanto, la optimización solo parece funcionar cuando se usa la misma variable, no cuando se usa la misma matriz. Pero esto significa que podemos ordenar las referencias de matriz en su lugar si asignamos alias una variable de matriz a la matriz a la que hace referencia algún escalar (utilizando Data::Alias ):

perl -MData::Alias -MO=Concise -e''my $ref; alias my @arr = @$ref; @arr = sort @arr'' e <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 3 <0> padsv[$ref:1,3] vM/LVINTRO ->4 4 <;> nextstate(main 2 -e:1) v:{ ->5 - <1> entersub vKS/INARGS ->a ... a <;> nextstate(main 3 -e:1) v:{ ->b - <1> ex-aassign vKS/64 ->e - <1> ex-list lK ->- b <0> pushmark s ->c d <@> sort lK/INPLACE ->e c <0> padrange[@arr:2,3] l/1 ->d - <0> padav[@arr:2,3] lRM* ->d - <1> ex-list lK ->- - <0> ex-pushmark s ->- - <0> ex-padav lRM* ->- -e syntax OK

... y la bandera inplace está nuevamente <@> sort lK/INPLACE ->e :-)

Esto significa que la respuesta de Eric Strom es incorrecta.