如何计算组合值的索引?无需存储所有组合方案
计算笛卡尔积组合的索引(无需生成全量组合)
核心思路
你的组合生成逻辑是最右侧维度优先迭代(即示例中third先遍历所有值,再轮到second,最后是first),可以通过维度权重累加的方式直接计算索引,完全不需要生成所有组合:
- 计算每个维度的「权重」:该维度每切换一个元素,索引的增量等于其右侧所有维度的长度乘积
- 找到目标组合中每个元素在对应维度列表里的位置索引
- 将每个元素的位置索引乘以对应维度的权重,求和得到最终索引
代码实现
function getCombinationIndex(array $list, array $combination) { $index = 0; $currentWeight = 1; // 最右侧维度的权重初始为1 // 从右往左遍历维度,计算权重并累加索引 $reversedKeys = array_reverse(array_keys($list)); foreach ($reversedKeys as $key) { $values = $list[$key]; // 找到当前元素在维度列表中的位置 $pos = array_search($combination[$key], $values); if ($pos === false) { throw new InvalidArgumentException("组合中的元素 {$combination[$key]} 不在维度 {$key} 的列表中"); } // 累加当前维度对索引的贡献 $index += $pos * $currentWeight; // 更新权重:左移一个维度时,权重为当前维度长度乘以原权重 $currentWeight *= count($values); } return $index; }
验证示例
用你提供的测试数据验证:
$list = [ 'first' => ['a', 'b', 'c', 'd'], 'second' => ['e', 'f'], 'third' => ['g', 'h'] ]; $combination = [ 'first' => 'd', 'second' => 'e', 'third' => 'h' ]; echo getCombinationIndex($list, $combination); // 输出:13
关键说明
- 需保证
$combination的键与$list的键完全对应,且元素存在于对应维度的列表中 - 权重从右往左迭代的逻辑,完全匹配你生成组合时的迭代顺序(最右侧维度先变更)
- 时间复杂度为O(n)(n为维度数量),空间复杂度为O(1),无需存储任何组合数据
内容的提问来源于stack exchange,提问作者Guh Bolinha
相关产品推荐
相关产品推荐

