-1

さまざまな組み合わせの文字列のセット/グループを含む配列があります (この例では小文字と大文字)。PHP を使用してこの配列をループし、元の文字列が構成できるすべての可能な組み合わせから連結された新しい文字列を生成しようとしています。

配列は次のようになります。

Array
(
    [0] => Array
        (
            [0] => ALFA
            [1] => alfa
        )
    [1] => Array
        (
            [0] => BETA
            [1] => beta
        )
    [2] => Array
        (
            [0] => DELTA
            [1] => delta
        )
)

私が望む出力は次のようになります。

ALFA
ALFA BETA
ALFA beta
ALFA DELTA
ALFA delta
ALFA BETA DELTA
ALFA BETA delta
ALFA beta beta
ALFA DELTA BETA
ALFA DELTA beta
ALFA delta BETA
ALFA delta beta
alfa 
alfa BETA
alfa beta
alfa DELTA
alfa delta
alfa BETA DELTA
alfa BETA delta
alfa beta beta
alfa DELTA BETA
alfa DELTA beta
alfa delta BETA
alfa delta beta
BETA
BETA ALFA
BETA alfa
BETA DELTA
BETA delta
BETA ALFA delta
BETA ALFA DELTA
BETA alfa delta
BETA alfa DELTA
BETA DELTA alfa
BETA DELTA ALFA
BETA delta alfa
BETA delta ALFA
beta
beta ALFA
...
...

私はこれを理解しようと一日中過ごしましたが、立ち往生しています。ご意見やご協力をいただければ幸いです。

4

3 に答える 3

0

これらの文字列の小文字バージョンのみを含む配列を格納し、それを動的に大文字にすることができます ( strtoupperが仕事をします)。

次に、ネストされたforループまたは再帰を使用して、配列の各要素とecho必要なさまざまな組み合わせを調べます(反復(または再帰)の2つのレイヤーで同じ要素にいる場合はスキップしてください)

于 2012-05-07T22:06:00.417 に答える
0

使用して

class CartesianProductIterator implements Iterator {
    protected $iterators;

    function __construct(array $iters) {
        $this->iterators = $iters;
    }

    function rewind() {
        foreach ($this->iterators as $it) {
            $it->rewind();
        }
    }

    function current() {
        $values = array();
        foreach ($this->iterators as $it) {
            $values[] = $it->current();
        }
        return $values;
    }

    function key() {
        return null;
    }

    function next() {
        /*      
        loop them in reverse, but exclude first
        why? example, odometer: 55199
        you always check the rightmost digit first to see if incrementing it would roll it over and need to be "rewound" to 0, 
        which causes the digit to the left to increase as well, which may also cause it to roll over as well, and so on...
        looping in reverse operates from right column to the left.
        we dont rewind the first column because if the leftmost column is on its last element and needs to roll over
        then this iterator has reached its end, and so rewind() needs to be explicitly called 
        */
        for ($i = count($this->iterators) - 1; $i > 0; --$i) {
            $it = $this->iterators[$i];
            $it->next();
            if ($it->valid()) {
                // were done advancing because we found a column that didnt roll over
                return;
            } else {
                $it->rewind();
            }
        }

        //if execution reached here, then all of the columns have rolled over, so we must attempt to roll over the left most column
        $this->iterators[0]->next();
    }

    function valid() {
        return $this->iterators[0]->valid();
    }
}

次のようにその用途を特化できます

$iterators = array();
foreach ($arr as $possibleChoicesForOneSlotInACombo) {
    //we add null as a way indicate "no value" as a choice for this slot
    $possibleChoicesForOneSlotInACombo[] = null;
    $iterators[] = new ArrayIterator($possibleChoicesForOneSlotInACombo);
}

foreach (new CartesianProductIterator($iterators) as $combo) {
    //filter out the possible nulls that might exist in this combo
    $strings = array_filter($combo, 'is_string');

    // make sure something exists, maybe they were all null
    if ($strings) {
        echo join(' ', $strings), "\n";
    }
}
于 2012-05-07T23:49:36.517 に答える