2012-04-25 2 views
0

私の問題:動物系譜データベースから、特定の母親の子孫を検索します。再帰関数は、1つのことをしていると言いますが、実際には別のことをしていますか?

私の解決策は、私がmySQLを使用しているので、すべての候補を取得し、PHPで再帰関数を使用することです。

私が使用しているデータベースモデルがうまく設計されているかどうか、より洗練されたデータを取得する方法、再帰関数自体が特に効率的かどうかなど、私が思いついた解決策がなぜあまり働いていないのかを洞察してください。出力をさまざまな場所でエコーすると、それは正しい子を返していると言います。実際の返品は対応していません。

私のsqlは、単にマザーIDにマッチしたすべての子IDを返し、子がキーでマザーが値である配列を作成します。データは、いくつかのすごみがあったことを機会に、私はハードコードに決めた正確な結果を持つ配列が返さ:

$aData = array("1"=>"20", "14"=>"12", "15"=>"14", "16"=>"10", "20"=>"13", "23"=>"20", "46"=>"20", "39"=>"12", "43"=>"13", "44"=>"13", "54"=>"1", "49"=>"1", "113"=>"46", "112"=>"54", "130"=>"15", "131"=>"43"); 

再帰関数:

// $targetMom is the mother whose descendants I want 
// $targetChild is each possible candidate 
// $childID is initially the same as $targetChild 
function recurseTree($data, $childID, $targetMom, $row, $targetChild){ 
    $momID = isset($data[$childID]) ? $data[$childID] : -1 ; 
    //echo "row: " . $row . " id: " . $childID . " mom ID: " . $momID . " target: ". $targetMom . " final target: ". $targetChild . "<br />"; 

    if ($momID == $targetMom){ 
     echo $momID . "==" . $targetMom . "; returning target: ". $targetChild . "<br/><br/>"; 
     return $targetChild;     
    } else if ($row == sizeof($data)) { // reached the end of the data array - no more to check 
     //echo "row: " . $row . "== size of array: " . sizeof($data) . "<br />"; 
     return -1; 
    } else if ($momID == -1) { // this child doesn't have a mom defined 
     //echo "momID == -1<br />"; 
     return -1; 
    } else { 
     //echo 'recursing<br/>'; 
     recurseTree($data, $momID, $targetMom, ++$row, $targetChild); 
    }    
} 

最後に、再帰関数の呼び出し、今の私はID 12 1人の特定の母で唯一興味場所:ちょうどrecurseTree()内のエコーのステートメントからの出力を見て、

$children = array(); 
foreach($aData as $k=> $v){ 
    $return = recurseTree($aData, $k, 12, 0, $k); 
    if ($return != -1 && $return != null) { 
     $children[] = $return; 
    } 
} 

だから、それはそれように思われます年代四つの値を返す:私は

Array 
(
    [0] => 14 
    [1] => 39 
) 

は、コードの改善上の任意のヒントを投稿してお気軽に、しかし:、しかし

12==12; returning target: 14 
12==12; returning target: 15 
12==12; returning target: 39 
12==12; returning target: 130 

を2つだけの値がそれにプッシュショーを構築された実際の配列をエコーechoステートメントが$ children配列の要素と一致しない理由に最も関心があります。ありがとう!

+0

私は決して機能を話すことを聞いた....あなたの質問のタイトルを確認してください。 – hakre

答えて

3

以下を行う必要があります。

return recurseTree($data, $momID, $targetMom, ++$row, $targetChild); 

それ以外の場合は、内側の反復によって得られた値は、バックの外側のスコープにそれを作ることはありません。

+0

ビンゴ...ありがとうDave;私は再帰関数を設計しなければならないので、非常に長い時間がかかりました。そして、私はPHPに錆びているのに役立ちません。 – earachefl

+0

私は実際にはまったく同じことを最近行っていて、なぜ2時間働いていないのか分かりませんでした。私はここ数週間Node.jsをたくさん行い、スコープの継承に満足しています... – DaveRandom