-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所需的各种组合(只需跳过在两层迭代(或递归)中位于同一元素上的情况)

于 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 回答
0

同意@Mahmoud Al-Qudsi,这似乎是一个奇怪的问题,如果阵列大于微不足道的大小,很容易破坏您的服务器。您确实意识到我们在这里谈论的是阶乘 - 如果您的数组有 10 个元素,那么仅在一种情况下,所有 10 个字符串的排列数就是 10!也就是 350 万 加上大小写版本,加上 9、8 等元素的字符串组合,我们正在谈论非常长的计算。在 10 个元素数组之后,每增加一个元素,计算的数量就会至少乘以 10,即 11 为 3500 万,12 为 3.5 亿......你得到了漂移。

于 2012-05-07T22:30:55.947 回答