¿Por qué el retorno de Matemáticas :: :: Producto cartesiano objetos bendito?
-
09-10-2019 - |
Pregunta
Matemáticas :: :: devoluciones de productos cartesianos una matriz de objetos bendecidos en lugar de una simple matriz de matrices. No podía entender por qué. En realidad, necesito hacer un trabajo extra (unbless) para utilizar los resultados ...
Solución
Una de las alternativas es el módulo Set :: CrossProduct , que producirá ordinaria , las referencias de matriz sin bendecir:
use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);
while (my $tuple = $iter->get){
...
}
o conseguir todas las tuplas a la vez:
my @tuples = $iter->combinations;
Otros consejos
He añadido una función cartesian
a href="http://search.cpan.org/perldoc?List%3a%3aGen" :: Gen recientemente:
-
cartesian CODE LIST_of_ARRAYREF
cartesian
calcula el producto cartesiano de cualquier número de refs de matriz, cada uno que puede ser de cualquier tamaño. devuelve un generadoruse List::Gen 'cartesian'; my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2]; print "@$product"; # 'a1 a2 b1 b2'
El "generador" devuelto es una matriz atado flojo que va a generar valores cuando se le preguntó por ellos. También existen métodos de acceso iterativos y otros:
my $pairs = cartesian {@_} [qw/$ @ %/], ['a'..'z'], [1 .. 3];
while (my @tuple = $pairs->next) { # $pairs->reset; #$pairs->index = 5; ...
print @tuple, ', ';
}
# $a1, $a2, $a3, $b1, $b2, $b3, $c1, $c2, $c3, $d1, $d2, $d3, $e1 ...
No sé qué tan grande se pone el que va a trabajar con el son, pero la ventaja de utilizar el enfoque anterior es que los requisitos de almacenamiento para el generador permanecen O(1)
my $digits = cartesian {join '' => @_} ([0..9]) x 10;
say for @$digits[10**9 - 3 .. 10**9 + 3];
# 0999999998
# 0999999999
# 1000000000
# 1000000001
# 1000000002
# 1000000003
que calcula sólo 6 elementos del conjunto, y tiendas de nada.
Como se puede ver en los ejemplos, el valor de retorno de cartesian
en sí es un objeto generador, pero los valores de retorno posteriores de ese objeto son cualquiera que sea el coderef pasó a rendimientos cartesian
. Así que si quieres referencias de la matriz, es tan simple como: cartesian {\@_} ...
Además, lo que hizo un trabajo extra que tiene que hacer para hacer frente a la referencia bendita? Una matriz bendito es todavía una matriz en todos los sentidos excepto por lo que volverá ref
. Si va a escribir la lógica de conmutación en función del tipo de referencia, Scalar::Util
de reftype
es lo que debe utilizar.
Se bendice las matrices devueltas por cartesian
de manera que cuando se ejecuta un código como el siguiente
$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;
... se puede detectar que $b
es el resultado de una llamada anterior al módulo.
Hacer una operación de producto cartesiano es algo trivial, si los datos devueltos por ese módulo no se ajusta a sus necesidades, considere la operación de escritura a sí mismo a partir de cero.
De todos modos, inspeccionar el código fuente del módulo revela que no es demasiado grande.