【问题标题】:recursively - all possibilities - PHP递归 - 所有可能性 - PHP
【发布时间】:2023-03-16 20:59:01
【问题描述】:

我有一个格式为:

$array['something_1'] = array('aother_1','aother_2',...,'aother_n')
$array['something_2'] = array('bother_1','bother_2',...,'bother_n')
...
$array['something_m'] = array('zother_1','zother_2',...,'zother_n')

n,m 是可变的

我需要做的是创建一个新表,其中包含所有具有 (x)other 的所有可能性的东西...

$array[] = array('something_1' => 'aother_1','something_2' => 'bother_1', ..., 'something_m' => 'zother_1');
$array[] = array('something_1' => 'aother_2','something_2' => 'bother_1', ..., 'something_m' => 'zother_1');
...
$array[] = array('something_1' => 'aother_n','something_2' => 'bother_n', ..., 'something_m' => 'zother_n');

基本上希望拥有所有可能的值的所有索引集。

一些真实的例子:

$input = array(
   'obj1' => array('val1','val2','val3'), 
   'obj2' => array('val4','val5')
);

$output = array(
   [] => array('obj1' => 'val1','obj2' => 'val4'),
   [] => array('obj1' => 'val2','obj2' => 'val4'),
   [] => array('obj1' => 'val3','obj2' => 'val4'),
   [] => array('obj1' => 'val1','obj2' => 'val5'),
   [] => array('obj1' => 'val2','obj2' => 'val5'),
   [] => array('obj1' => 'val3','obj2' => 'val5'),
)

实际案例比这个例子大得多...可能包含大约 1000 个对象,每个对象大约有 20 个值。

通常在那个例子中我可以使用双 foreach ...但是对于 1000 个对象,使用 1000 个 foreach 似乎有点...白痴:D

【问题讨论】:

  • 这个问题的信息有点少。能分享一下你尝试过的,遇到了什么问题吗?
  • 递归有什么问题?这可能会有所帮助:stackoverflow.com/questions/14006609/…
  • 我在递归思维方面很糟糕......我真的很难尝试任何尝试......需要递归,因为我们真的不知道有多少元素...... . 要么索引两个值。
  • 至少,你应该画一个预期输出的问题..
  • 如果您尝试了一些尝试(即使这是非常糟糕的尝试),那么帮助您会更容易,因此我们可以对其进行处理并向您展示您错在哪里。

标签: php


【解决方案1】:

这是一个采用 n 和 m 任意组合的解决方案,并且不使用递归逻辑(您不喜欢)。

它有效地跟踪每个子数组中的元素数量,将它们减少 1,如果它们达到 -1,则设置回原始计数。

它还使用一些类似链接列表的行为(当第一个键 'curindex' 不能降低时终止。)

<?php
$input = array(
   'obj1' => array('val1','val2','val3'), 
   'obj2' => array('val4','val5'),
   'obj3' => array('val6','val7')
);  

// find last key
$keys = array_keys($input);
$lastKey = $keys[count($keys)-1];

// create currentindex and maxindex for each 
$CMI = array();

$former = '';
foreach ($input as $key => $valARR){
    $CMI[$key]["maxindex"] = count($valARR)-1;
    $CMI[$key]["curindex"] = count($valARR)-1;
    // linkedlist like behaviour. obj3 -> obj2 -> obj1 -> ''
    $CMI[$key]["former"] = $former;
    $former = $key;     
}

$output = array();
$bRunning = true;

while ($bRunning){
    $oneCombi = array();
    foreach ($input as $key => $valARR){
        $oneCombi[$key] = $valARR[$CMI[$key]["curindex"]];
    }
    $output[] = $oneCombi;

    // Now lower curindex of last one, all the way up to first one, then quit.
    $bLowering = true;
    $curKey = $lastKey;
    while ($bLowering){
        $CMI[$curKey]["curindex"]--;
        if ($CMI[$curKey]["curindex"] == -1){
            $CMI[$curKey]["curindex"] = $CMI[$curKey]["maxindex"];
            $curKey = $CMI[$curKey]["former"];
            if ($curKey == ''){
                // no more combinations
                $bLowering = false;
                $bRunning = false;
            }
        } else {
            $bLowering = false;
        }
    }
}

// optionally reverse to match your original example:
$output = array_reverse($output);

echo "endresult:<pre>";
var_dump($output);
echo "</pre>";

?>

【讨论】:

    猜你喜欢
    • 2011-05-15
    • 2016-03-20
    • 2011-05-31
    • 1970-01-01
    • 2014-02-28
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多