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 ...

¿Fue útil?

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 generador

    use 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top