從 N 個元素中任意選取(至少 1 個)的組合總數 = 2^N - 1(每個元素選/不選,排除全不選)。
若需分類統計每種選取個數的組合數:
C(N,1) = NC(N,2) = N(N-1)/2C(N,k)Σ C(N,k) = 2^N - 1<?php
function combinations(array $elements): array {
$result = [];
$n = count($elements);
// 位掩碼法:1 到 2^n-1
for ($mask = 1; $mask < (1 << $n); $mask++) {
$combo = [];
for ($i = 0; $i < $n; $i++) {
if ($mask & (1 << $i)) {
$combo[] = $elements[$i];
}
}
$result[] = $combo;
}
return $result;
}
// 使用
$arr = [1, 2, 3, 4, 5];
$combos = combinations($arr);
echo "總組合數: " . count($combos); // 31 = 2^5 - 1
print_r($combos);
class CombinationIterator implements Iterator {
private array $elements;
private int $n;
private int $mask = 1; // 從 1 開始,跳過空集
public function __construct(array $elements) {
$this->elements = array_values($elements);
$this->n = count($this->elements);
}
public function current(): array {
$combo = [];
for ($i = 0; $i < $this->n; $i++) {
if ($this->mask & (1 << $i)) $combo[] = $this->elements[$i];
}
return $combo;
}
public function next(): void { $this->mask++; }
public function key(): int { return $this->mask; }
public function valid(): bool { return $this->mask < (1 << $this->n); }
public function rewind(): void { $this->mask = 1; }
}
// 使用
foreach (new CombinationIterator(['A','B','C','D']) as $combo) {
echo implode(',', $combo) . "\n";
}
// 輸出 15 行組合
(1 << $n) - 1 直接計算,O(1)。C(N,k) 組合生成器(遞歸/迭代),避免全量生成再過濾。