2011-01-30 22 views
0

この再帰関数の結果を返す最もクリーンな方法は何ですか?再帰結果スタック

現時点では、一番上の呼び出しを返すのは当然です。

///////これは完全な関数で、ここで末尾再帰を使用できますか?出力は、値を渡すときに構築している配列です。

<?php  
//Page best viewed from page source 

//Takes an array of objects that have ID and Parent and organizes the tree into an array representing a set of objectID's by depth 

// poor spelling ahead =P 

function level_keys($array,$depth=-1,$level=0,$output=null){ 

// initialize the functions parameters run once at start and not in subsequent self calls 

if($level == 0 && $depth != 0){ 
    $output[][]=0; 
    $level++; 
     foreach($array as $key=>$node){ 
      if($node->parent==0){ 
       $output[$level][] = $node->id; 
       unset($array[$key]); 
      } 
     } 
      unset($key); unset($node); 
$level++; 
$depth--; 

} 

// set recursion loop and run main part of function 

if ( !empty($array) && $depth != 0){ 

    echo 'depth:'.$depth."\n"; 

    foreach($output[$level-1] as $parent){ 
     foreach($array as $key=> $child){ 
      if($parent == $child->parent){ 
      $output[$level][] = $child->id; 
      unset($array[$key]); 
      } 
     } 
    } 
     unset($id); unset($parent); unset($key); unset($child); 
$depth--; 
$level++; 
     if(!empty($array) && $depth !=0){ 
      // make sure to pass the output back out to the top most level 
      $output = level_keys($array,$depth,$level,$output,$depth_at); 
     } 
} 

return $output; 

} 
?> 

答えて

1

本当に必要なのは、配列の要素数を数えないと思います。

このような再帰関数を実行すると、末尾再帰型(実際には、この最適化がPHPにあるかどうかわかりません。ここでは、アキュムレータとして機能することができますが、それを使用しない$カウントがあります。

function recursion_trigger ($input, $count = 0) 
{ 
    if (!empty($input)) { 
    array_pop($input); 
    return recursion_trigger($input, $count + 1); 
    } 
    return $count; 
} 

このように、これは動作し、末尾再帰的です:-)。

+0

ハハいいえ、問題の重要でない部分を抽象化するのは良い方法でした。また、私はここで起こった他の人のためにこのリンクを見つけました。 http://www.c2.com/cgi/wiki?TailRecursion – Prospero

+0

私はテール再帰の利点を理解していますが、私はそれを上記の質問で編集した関数にどのように適用できますか? – Prospero

1

あなたはrecursion_trigger

if(!empty($input)){ 
    $count = recursion_trigger($input,$count); 
} 

EDITの戻り値を使用して$count変数を更新する必要があります

うまくいけば、次はあなたはそれが働いてどのように視覚化するのに役立ちます:

recursion_trigger (array("This", "Is", "A", "Sample"), 0) 
    recursion_trigger (array("This", "Is", "A"), 1) 
    recursion_trigger (array("This", "Is"), 2) 
     recursion_trigger (array("This"), 3) 
     recursion_trigger (array(), 4) 
+0

ありがとうございました。私はそれがなぜ機能するのか理解していますが、それがどのように動作するかを視覚化するのにはまだ問題があります。 – Prospero

+0

@Doodle:更新された投稿を参照してください。 –

1

あなたが思っていた方法はおそらく、つまり$countは永続的でしたが、値による呼び出しのためではありませんでした。このバージョンは、参照を使用しても動作します。

function recursion_trigger($input, &$count = 0){ 

     if(!empty($input)){ 
       array_pop($input); 
       $count++; 
       if(!empty($input)){ 
       recursion_trigger($input,$count); 
       } 
     } 

echo $count; 
return $count; 


} 
+0

私はそれを考えていましたが、これは最終的にJavaの関数になります。私は、すべてがうまくいくかどうかを視覚化しようとしていただけで、PHPは非常に速い言語です。ありがとうございました。 – Prospero