0

私の問題: 動物の系図データベースから、特定の母親の子孫を取得します。

私の解決策は、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 人だけに関心があります。

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

したがって、recurseTree() 内の echo ステートメントからの出力を見るだけで、4 つの値が返されているように見えます。

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

ただし、構築された実際の配列をエコーすると、それにプッシュされた 2 つの値のみが表示されます。

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

コードを改善するためのヒントを自由に投稿してください。ただし、echo ステートメントが $children 配列の要素と一致しない理由に最も関心があります。ありがとう!

4

1 に答える 1

3

必要がある:

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

そうしないと、内側の反復によって取得された値が外側のスコープに戻ることはありません。

于 2012-04-25T10:25:34.740 に答える