Frage

Math :: cartesianischen :: Artikel Renditen ein Array des Sel Objekte anstelle einer einfachen Array von Arrays. Ich konnte nicht herausfinden, warum. Ich brauche eigentlich einige zusätzliche Arbeit (unbless) zu tun, um die Ergebnisse zu verwenden ...

War es hilfreich?

Lösung

Eine Alternative ist das Modul Set :: Crossproduct , die gewöhnlichen ergeben wird , unblessed Array Referenzen:

use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);

while (my $tuple = $iter->get){
    ...
}

oder erhalten alle Tupel auf einmal:

my @tuples = $iter->combinations;

Andere Tipps

Ich habe eine cartesian Funktion List :: Gen kürzlich:

  • cartesian CODE LIST_of_ARRAYREF

    cartesian berechnet die kartesisches Produkt von einer beliebigen Anzahl von Array refs, die jede beliebige Größe sein kann. kehrt ein Generator

    use List::Gen 'cartesian';
    my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2];
    print "@$product"; # 'a1 a2 b1 b2'
    

Der „Generator“ zurückgegeben wird, ist ein faules gebunden Array, das Wert erzeugen, wenn sie gefragt. Darüber hinaus gibt es iterative und andere Zugriffsmethoden:

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

Ich weiß nicht, wie groß die Sets, die Sie arbeiten werden, aber der Vorteil für den oben beschriebenen Ansatz besteht darin, dass der Speicherbedarf für den Generator bleiben 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

, die nur 6 Elemente des Satzes berechnet und speichert nichts.

Wie Sie aus den Beispielen sehen können, ist der Rückgabewert von cartesian selbst ist ein Generator-Objekt, aber das Objekt der nachfolgenden Rückgabewerte sind unabhängig von der Codereferenz zu cartesian kehrt übergeben. Also, wenn Sie Array Referenzen wollen, es ist so einfach wie: cartesian {\@_} ...


Auch, was zusätzliche Arbeit müssen Sie mit dem gesegneten Bezug zu beschäftigen zu tun? Eine gesegnete Array ist immer noch ein Array in jeder Hinsicht außer dem, was ref zurückkehren wird. Wenn Sie Schaltlogik schreiben, basierend auf Referenztyp, Scalar::Util des reftype ist das, was Sie verwenden sollen.

Es segnet die von cartesian zurückgegebenen Arrays so, dass, wenn einige Code wie die folgenden ausgeführt wird,

$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;

... kann es erkennen, dass $b ist das Ergebnis eines vorherigen Aufruf zum Modul.

eine kartesische Produktoperation macht dir etwas trivial ist, wenn die Daten als von diesem Modul zurückgegeben nicht Ihre Anforderungen passen, betrachten writting den Betrieb selbst von Grunde auf neu.

Wie auch immer, das Modul Quellcode Inspektion deckt sie nicht zu groß ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top