【问题标题】:converting plain array to multidimensional one using recursion使用递归将普通数组转换为多维数组
【发布时间】:2013-03-19 10:29:57
【问题描述】:

大家!

我一直在尝试编写递归函数。 =( 这是我的函数,正如我所料,它将我的普通数组变成多维数组。

function BuildTree($src, $index=0) {
    foreach ($src as $index=>$curentItem) {
        $nextItem = (is_array($src[$index+1]))?$src[$index+1]:false;
        unset($src[$index]);
        if ($nextItem['d']==$curentItem['d']) $brunchArray[] = $curentItem['n'];
        if ($nextItem['d']>$curentItem['d']) $brunchArray['childrens'] = BuildTree($src, $index);
        if (!$nextItem || $nextItem['d']<$curentItem['d']) return $brunchArray;
    }
}

输入数组是这样的:

$input = array (
array(
        'n' => 'Articles',
        'd' => 0
    ),
array(
        'n' => 'Article 1',
        'd' => 1
    ),
array(
        'n' => 'Books',
        'd' => 0
    ),
array(
        'n' => 'Book 1',
        'd' => 1
    ),
array(
        'n' => 'Book 2',
        'd' => 1
    ),
array(
        'n' => 'Chapter 1',
        'd' => 2
    ),
array(
        'n' => 'Chapter 2',
        'd' => 2
    )
);

我希望它被转换成这个:

array (
    array(
            'n' => 'Articles',
            'd' => 0,
            'childrens' => array (
                array(
                        'n' => 'Article 1',
                        'd' => 1
                    ),
            )
        ),
    array(
            'n' => 'Books',
            'd' => 0,
            'childrens' => array (
                array(
                        'n' => 'Book 1',
                        'd' => 1
                    ),
                array(
                        'n' => 'Book 2',
                        'd' => 1
                        'childrens' => array (
                            array(
                                    'n' => 'Chapter 1',
                                    'd' => 2
                                ),
                            array(
                                    'n' => 'Chapter 2',
                                    'd' => 2
                                )
                        )
                    )
            )
        )
)

我已经花了三个小时试图解决这个问题。 =( 任何帮助将不胜感激!

【问题讨论】:

  • 你的程序应该如何猜测哪一项是哪一项的子项?
  • 它们已经按正确的顺序排序了
  • 一定要递归吗?
  • 我想是这样,因为我们不知道输入数组中有多少深度级别
  • 接受挑战:D

标签: php recursion multidimensional-array


【解决方案1】:

这是一个没有递归的解决方案:

function convert($arr) {
    $stack = array();
    $output = array();
    $arr[] = array('d' => -1); // Dummy record at the end
    for($i = 0; $i < count($arr); $i++) {
        while(!empty($stack) && $stack[count($stack) - 1]['d'] > $arr[$i]['d']) {
            $current_d = $stack[count($stack) - 1]['d'];
            $children = array();
            while(!empty($stack) && $stack[count($stack) - 1]['d'] >= $current_d) {
                $children[] = array_pop($stack);
            }
            $children = array_reverse($children);
            if(empty($stack)) {
                foreach($children as $child) {
                    $output[] = $child;
                }
            } else {
                $stack[count($stack) - 1]['children'] = $children;
            }
        }
        $stack[] = $arr[$i];
    }
    return $output;
}

$input = array (
array(
        'n' => 'Articles',
        'd' => 0
    ),
array(
        'n' => 'Article 1',
        'd' => 1
    ),
array(
        'n' => 'Books',
        'd' => 0
    ),
array(
        'n' => 'Book 1',
        'd' => 1
    ),
array(
        'n' => 'Book 2',
        'd' => 1
    ),
array(
        'n' => 'Chapter 1',
        'd' => 2
    ),
array(
        'n' => 'Chapter 2',
        'd' => 2
    )
);

var_dump(convert($input));

【讨论】:

  • 酷!我很惊讶它可以这样做,但你证明了这一点。稍后我会尝试比较哪个更快。
  • 如何在本网站上将两个答案都标记为正确?有可能吗?
  • 不幸的是你不能,但你必须牢记你的问题:“我一直在尝试编写递归函数”:(只需投票以传递识别的答案:D
【解决方案2】:

使用相同的$input:

$output = array();

function buildTree(&$input, &$output, &$current, $level = 0) {
    if(!$input)
        return;
    $next = array_shift($input);
    if($next['d'] == $level) {
        $current[] = $next;
        return buildTree($input, $output, $current, $level);
    } else if($next['d'] == $level + 1) {
        $current[count($current) - 1]['childrens'] = array($next);
        return buildTree($input, $output, $current[count($current) - 1]['childrens'], $level + 1);
    } else {
        $output[] = $next;
        return buildTree($input, $output, $output, 0);
    }
}

buildTree($input, $output, $output);

var_dump($output);

【讨论】:

  • 谢谢 :D 我喜欢解决这个问题!好问题:)
  • @aram90 在此处发布了“非递归”解决方案。它也可以正常工作。比较哪个更快会很有趣。
  • 这不是像典型斐波那契例子那样的传统递归,所以它不是指数时间。事实上,它是线性的——就像他的一样——所以差异不会很明显。
猜你喜欢
  • 2015-05-30
  • 2019-04-28
  • 2012-06-10
  • 2021-07-19
  • 2015-11-11
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多