복붙노트

평범한 사람은 PHP를 사용하는 재귀 함수 란 무엇입니까?

PHP

평범한 사람은 PHP를 사용하는 재귀 함수 란 무엇입니까?

누구든지 PHP (피보나치 사용하지 않고)에서 평범한 언어로 예제를 사용하여 재귀 함수를 설명해 주시겠습니까? 나는보기를 보았지만 피보나치는 완전히 나를 잃어 버렸다!

미리 감사드립니다 ;-) 또한 웹 개발에서 얼마나 자주 사용합니까?

해결법

  1. ==============================

    1.재귀 함수는 자신을 호출하는 함수입니다.

    재귀 함수는 자신을 호출하는 함수입니다.

    함수 자체를 계속 호출하는 경우 중지 시점을 어떻게 알 수 있습니까? 기본 케이스라고하는 조건을 설정합니다. 기본 케이스는 우리의 재귀 호출을 언제 멈출 지 알려주고, 그렇지 않으면 무한 루프를 반복합니다.

    수학에 대한 강한 배경을 가지고 계기 때문에 좋은 학습 사례는 무엇 이었습니까? 아래의 설명에 따르면, 계승 함수가 너무 많을 수 있습니다, 당신이 원할 경우에 대비해 여기에 남겨 두겠습니다.

    function fact($n) {
      if ($n === 0) { // our base case
         return 1;
      }
      else {
         return $n * fact($n-1); // <--calling itself.
      }
    }
    

    웹 개발에서 재귀 함수를 사용하는 것과 관련하여 재귀 호출을 사용하는 것에 개인적으로 의지하지 않습니다. 재귀에 의존하는 것은 나쁜 습관이라고 생각 하겠지만, 첫 번째 선택이되어서는 안됩니다. 제대로 사용하지 않으면 치명적일 수 있습니다.

    디렉토리 예제와 경쟁 할 수는 없지만, 이것이 다소 도움이되기를 바랍니다.

    또한이 질문을 확인하는 것이 도움이 될 것입니다. 여기서 대답은 평범한 용어로 재귀 함수가 어떻게 작동하는지 보여줍니다. OP의 질문이 Java를 다루는 경우에도 개념은 동일하지만,

  2. ==============================

    2.예를 들어 특정 디렉토리의 하위 디렉토리에있는 모든 파일을 인쇄하는 것입니다 (이 디렉토리에 기호 링크가 없어도 기능이 손상 될 수 있습니다). 모든 파일을 인쇄하는 의사 코드는 다음과 같습니다.

    예를 들어 특정 디렉토리의 하위 디렉토리에있는 모든 파일을 인쇄하는 것입니다 (이 디렉토리에 기호 링크가 없어도 기능이 손상 될 수 있습니다). 모든 파일을 인쇄하는 의사 코드는 다음과 같습니다.

    function printAllFiles($dir) {
        foreach (getAllDirectories($dir) as $f) {
            printAllFiles($f); // here is the recursive call
        }
        foreach (getAllFiles($dir) as $f) {
            echo $f;
        }
    }
    

    아이디어는 모든 하위 디렉토리를 먼저 인쇄 한 다음 현재 디렉토리의 파일을 인쇄하는 것입니다. 이 아이디어는 모든 하위 디렉토리에 적용되며, 모든 하위 디렉토리에 대해이 함수를 반복적으로 호출하는 이유가 있습니다.

    이 예제를 시도하려면 특수 디렉토리를 확인해야합니다. 그리고 .. 그렇지 않으면 항상 printAllFiles ( ".")를 호출해야합니다. 또한 인쇄 할 내용과 현재 작업 디렉토리가 무엇인지 확인해야합니다 (opendir (), getcwd () 참조).

  3. ==============================

    3.재귀는 반복되는 것입니다. 내부에서 자신을 호출하는 함수와 같습니다. 다소 의사적인 예를 들어 설명해 드리겠습니다.

    재귀는 반복되는 것입니다. 내부에서 자신을 호출하는 함수와 같습니다. 다소 의사적인 예를 들어 설명해 드리겠습니다.

    맥주를 마시는 친구들과 함께 있다고 상상해보십시오.하지만 자정 전에 집에 오지 않으면 아내가 지옥을 넘겨 줄 것입니다. 이를 위해 orderAndDrinkBeer ($ time) 함수를 작성해 보겠습니다. $ time은 자정을 뺀 시간으로 현재 음료수를 마시고 집에 도착하는 시간을 나타냅니다.

    술집에 도착하면 첫 번째 맥주를 주문하고 술을 마시기 시작합니다.

    $timeToGoHome = '23';  // Let's give ourselves an hour for last call and getting home
    
    function orderAndDrinkBeer($timeToGoHome) {  // Let's create the function that's going to call itself.
        $beer = New Beer();  // Let's grab ourselves a new beer
        $currentTime = date('G'); // Current hour in 24-hour format
    
        while ($beer->status != 'empty') {  // Time to commence the drinking loop
            $beer->drink();  // Take a sip or two of the beer(or chug if that's your preference)
        }
    
        // Now we're out of the drinking loop and ready for a new beer
    
        if ($currentTime < $timeToGoHome) { // BUT only if we got the time
            orderAndDrinkBeer($timeToGoHome);  // So we make the function call itself again!
        } else {  // Aw, snap!  It is time :S
            break; // Let's go home :(
        }
    }
    

    이제 당신이 너무 술에 취해 맥주를 충분히 마시지 못해서 술에 취해서 아내가 집에있을 때와 상관없이 소파에서 자게 할 수 있기를 바랍니다.

    하지만 그래, 그건 재귀가 어떻게되는지 꽤 많이있다.

  4. ==============================

    4.그 자체를 호출하는 함수. 나무와 같이 반복되는 특정 데이터 구조를 걷는 데 유용합니다. HTML DOM이 전형적인 예입니다.

    그 자체를 호출하는 함수. 나무와 같이 반복되는 특정 데이터 구조를 걷는 데 유용합니다. HTML DOM이 전형적인 예입니다.

    자바 스크립트의 트리 구조와 트리를 '걷는'재귀 함수의 예입니다.

        1
       / \
      2   3
         / \
        4   5
    

    --

    var tree = {
      id: 1,
      left: {
        id: 2,
        left: null,
        right: null
      },
      right: {
        id: 3,
        left: {
          id: 4,
          left: null,
          right: null
        },
        right: {
          id: 5,
          left: null,
          right: null
        }
      }
    };
    

    트리를 걷기 위해 동일한 함수를 반복적으로 호출하여 현재 노드의 자식 노드를 같은 함수로 전달합니다. 그런 다음 함수를 다시 왼쪽 노드에서 호출 한 다음 오른쪽에서 호출합니다.

    이 예제에서는 트리의 최대 깊이를 구합니다.

    var depth = 0;
    
    function walkTree(node, i) {
    
      //Increment our depth counter and check
      i++;
      if (i > depth) depth = i;
    
      //call this function again for each of the branch nodes (recursion!)
      if (node.left != null) walkTree(node.left, i);
      if (node.right != null) walkTree(node.right, i);
    
      //Decrement our depth counter before going back up the call stack
      i--;
    }
    

    마지막으로 함수를 호출합니다.

    alert('Tree depth:' + walkTree(tree, 0));
    

    재귀를 이해하는 가장 좋은 방법은 런타임에 코드를 단계별로 실행하는 것입니다.

  5. ==============================

    5.간단히 말하면 : 재귀 함수는 자신을 호출하는 함수입니다.

    간단히 말하면 : 재귀 함수는 자신을 호출하는 함수입니다.

  6. ==============================

    6.재귀는 "이 일이 끝날 때까지 다시해라"는 멋진 말입니다.

    재귀는 "이 일이 끝날 때까지 다시해라"는 멋진 말입니다.

    두 가지 중요한 것들 :

    간단한 작업을 상상해보십시오 : 도서 스택을 사전 순으로 정렬하십시오. 간단한 과정은 처음 두 권의 책을 가져 와서 정렬합니다. 이제 재귀적인 부분이 있습니다 : 더 많은 책이 있습니까? 그렇다면 다시하십시오. "다시해라"는 재귀입니다. "더 이상의 책이 있습니까?"라는 테스트가 있습니다. "아니오, 더 이상 책이 없습니다"는 기본 사례입니다.

  7. ==============================

    7.정의되지 않은 한정된 시간 동안 작업을 수행하기 위해 함수를 호출 할 때 매우 간단합니다. 내 자신의 코드에서 예제, 다차원 카테고리 트리를 채우는 함수

    정의되지 않은 한정된 시간 동안 작업을 수행하기 위해 함수를 호출 할 때 매우 간단합니다. 내 자신의 코드에서 예제, 다차원 카테고리 트리를 채우는 함수

    function category_tree($parent=0,$sep='')
    {
        $q="select id,name from categorye where parent_id=".$parent;
        $rs=mysql_query($q);
        while($rd=mysql_fetch_object($rs))
        {
            echo('id.'">'.$sep.$rd->name.'');
            category_tree($rd->id,$sep.'--');
        }
    }
  8. ==============================

    8.나 자신이 여기 있다는 것을 알았을 때 나는 발견했다. http : //www.elated.com/articles/php-recursive-functions/

    나 자신이 여기 있다는 것을 알았을 때 나는 발견했다. http : //www.elated.com/articles/php-recursive-functions/

    그것 때문에 한가지 :

    호출 된 함수가 메모리에 생성 될 때 함수 (새 인스턴스가 만들어 짐)

    따라서 재귀 함수는 자체를 호출하지 않지만 호출하는 다른 인스턴스는 메모리에서 메모리가 아닌 일부 마법을 사용합니다. 몇 가지 값을 반환하는 메모리의 두 인스턴스 - 예를 들어 함수 a가 함수 b를 호출 할 때이 동작은 동일합니다. 재귀 함수가 자체의 새 인스턴스를 호출하는 경우뿐만 아니라 두 인스턴스가 있습니다.

    종이에있는 인스턴스로 메모리를 그리십시오. 의미가 있습니다.

  9. ==============================

    9.재귀는 루프에 대한 대안이며, 코드에서 더 명확하거나 우아함을 가져 오는 경우는 거의 없습니다. 좋은 예가 Progman의 대답으로 주어졌습니다. 재귀를 사용하지 않는다면 현재 그가 어떤 디렉토리에 있는지 추적해야합니다 (이것은 상태라고 함). 재귀는 스택을 사용하여 부기를 수행 할 수있게합니다 메소드의 복귀 주소가 저장 됨)

    재귀는 루프에 대한 대안이며, 코드에서 더 명확하거나 우아함을 가져 오는 경우는 거의 없습니다. 좋은 예가 Progman의 대답으로 주어졌습니다. 재귀를 사용하지 않는다면 현재 그가 어떤 디렉토리에 있는지 추적해야합니다 (이것은 상태라고 함). 재귀는 스택을 사용하여 부기를 수행 할 수있게합니다 메소드의 복귀 주소가 저장 됨)

    팩토리얼과 피보나치의 표준 예제는 루프로 교체하기 쉽기 때문에 개념을 이해하는 데 유용하지 않습니다.

  10. ==============================

    10.기본적으로. 완료 될 때까지 계속 호출합니다.

    기본적으로. 완료 될 때까지 계속 호출합니다.

    void print_folder(string root)
    {
        Console.WriteLine(root);
        foreach(var folder in Directory.GetDirectories(root))
        {
            print_folder(folder);
        }
    }
    

    또한 루프와 함께 작동합니다!

    void pretend_loop(int c)
    {
        if(c==0) return;
        print "hi";
        pretend_loop(c-);
    }
    

    인터넷 검색을 시도 할 수도 있습니다. "Did you mean?"(클릭하십시오.)을 클릭하십시오. http://www.google.com/search?q=recursion&spell=1

  11. ==============================

    11.실용적인 예가 있습니다 (이미 여러 가지 좋은 예가 있습니다). 거의 모든 개발자에게 유용한 것을 추가하고 싶었습니다.

    실용적인 예가 있습니다 (이미 여러 가지 좋은 예가 있습니다). 거의 모든 개발자에게 유용한 것을 추가하고 싶었습니다.

    어떤 시점에서 개발자는 API 또는 일부 유형의 객체 또는 배열에서 응답으로 객체를 구문 분석해야합니다.

    이 함수는 처음에는 매개 변수를 포함 할 수있는 객체를 구문 분석하기 위해 처음에는 호출되지만 객체에 다른 객체 또는 배열도 포함되어 있으면 어떻게됩니까? 이 문제를 해결해야하며 대부분의 경우 기본 함수가 이미이를 수행하므로 함수는 키 또는 값이 객체인지 배열인지 확인한 후 다시 자신을 호출하고이 새 객체 또는 배열을 구문 분석합니다. 궁극적으로 반환되는 것은 가독성을 위해 한 줄에 각 매개 변수를 만드는 문자열이지만 로그 파일에 값을 쉽게 로그하거나 DB에 삽입 할 수 있습니다.

    $ prefix 매개 변수를 추가하여 parent 요소를 사용하여 end 변수를 설명하여 값이 무엇인지 확인할 수있게했습니다. null 값과 같은 것은 포함하지 않지만이 예에서 수정 될 수 있습니다.

    객체가있는 경우 :

    $apiReturn = new stdClass();
    $apiReturn->shippingInfo = new stdClass();
    $apiReturn->shippingInfo->fName = "Bill";
    $apiReturn->shippingInfo->lName = "Test";
    $apiReturn->shippingInfo->address1 = "22 S. Deleware St.";
    $apiReturn->shippingInfo->city = "Chandler";
    $apiReturn->shippingInfo->state = "AZ";
    $apiReturn->shippingInfo->zip = 85225;
    $apiReturn->phone = "602-312-4455";
    $apiReturn->transactionDetails = array(
        "totalAmt" => "100.00",
         "currency" => "USD",
         "tax" => "5.00",
         "shipping" => "5.00"
    );
    $apiReturn->item = new stdClass();
    $apiReturn->item->name = "T-shirt";
    $apiReturn->item->color = "blue";
    $apiReturn->item->itemQty = 1;
    

    사용 :

    var_dump($apiReturn);
    

    그것은 반환 할 것이다 :

    다음은 각 매개 변수에 대해 줄 바꿈이있는 문자열로 구문 분석하는 코드입니다.

    function parseObj($obj, $prefix = ''){
        $stringRtrn = '';
        foreach($obj as $key=>$value){
            if($prefix){
                switch ($key) {
                    case is_array($key):
                        foreach($key as $k=>$v){
                            $stringRtrn .= parseObj($key, $obj);
                        }
                        break;
                    case is_object($key):
                        $stringRtrn .= parseObj($key, $obj);
                        break;
                    default:
                        switch ($value) {
                            case is_array($value):
                                $stringRtrn .= parseObj($value, $key);
                                break;
                            case is_object($value):
                                $stringRtrn .= parseObj($value, $key);
                                break;
                            default:
                                $stringRtrn .= $prefix ."_". $key ." = ". $value ."<br>";
                                break;
                        }
                        break;
                }
            } else { // end if($prefix)
                switch($key){
                    case is_array($key):
                        $stringRtrn .= parseObj($key, $obj);
                        break;
                    case is_object($key):
    
                        $stringRtrn .= parseObj($key, $obj);
                        break;
                    default:
                        switch ($value) {
                            case is_array($value):
                                $stringRtrn .= parseObj($value, $key);
                                break;
                            case is_object($value):
                                $stringRtrn .= parseObj($value, $key);
                                break;                      
                            default:
                                $stringRtrn .= $key ." = ". $value ."<br>";
                                break;
                        } // end inner switch 
                } // end outer switch
            } // end else
        } // end foreach($obj as $key=>$value)
        return $stringRtrn;
    } // END parseObj()
    

    그러면 다음과 같이 객체가 반환됩니다.

    shippingInfo_fName = Bill
    shippingInfo_lName = Test
    shippingInfo_address1 = 22 S. Deleware St.
    shippingInfo_city = Chandler
    shippingInfo_state = AZ
    shippingInfo_zip = 85225
    phone = 602-312-4455
    transactionDetails_totalAmt = 100.00
    transactionDetails_currency = USD
    transactionDetails_tax = 5.00
    transactionDetails_shipping = 5.00
    item_name = T-shirt
    item_color = blue
    item_itemQty = 1
    

    나는 if와 혼란을 피하기 위해 switch 문을 중첩했다. . . 다른 경우라면 . . . 그렇지 않으면, 거의 길었다. 도움이된다면 if 조건을 물어 보면 필요한 조건을 붙일 수 있습니다.

  12. ==============================

    12.디렉토리 트리를 걷는 것이 좋은 예입니다. 배열을 처리하는 것과 비슷한 작업을 수행 할 수 있습니다. 다음은 단순히 문자열, 간단한 문자열 배열 또는 임의의 깊이의 문자열 중첩 된 배열을 처리하는 간단한 재귀 함수입니다. 'hello'인스턴스를 'goodbye'문자열 또는 배열 또는 any 값으로 대체합니다. 서브 어레이 :

    디렉토리 트리를 걷는 것이 좋은 예입니다. 배열을 처리하는 것과 비슷한 작업을 수행 할 수 있습니다. 다음은 단순히 문자열, 간단한 문자열 배열 또는 임의의 깊이의 문자열 중첩 된 배열을 처리하는 간단한 재귀 함수입니다. 'hello'인스턴스를 'goodbye'문자열 또는 배열 또는 any 값으로 대체합니다. 서브 어레이 :

    function replaceHello($a) {
        if (! is_array($a)) {
            $a = str_replace('hello', 'goodbye', $a);
        } else {
            foreach($a as $key => $value) {
                $a[$key] = replaceHello($value);
            }
        }
        return $a
    }
    

    어떤 시점에서 처리중인 "물건"이 배열이 아니기 때문에 언제 종료해야하는지 알 수 있습니다. 예를 들어, replaceHello ( 'hello')를 호출하면 'goodbye'가 반환됩니다. 문자열의 배열을 보내면 배열의 모든 멤버에 대해 한 번 호출되지만 처리 된 배열을 반환합니다.

  13. ==============================

    13.Anthony Forloney의 예에 특정 값 (예 : "1")을 추가하면 모든 것이 명확 해집니다.

    Anthony Forloney의 예에 특정 값 (예 : "1")을 추가하면 모든 것이 명확 해집니다.

    function fact(1) {
      if (1 === 0) { // our base case
      return 1;
      }
      else {
      return 1 * fact(1-1); // <--calling itself.
      }
    }
    

    실물:

    function fact($n) {
      if ($n === 0) { // our base case
        return 1;
      }
      else {
      return $n * fact($n-1); // <--calling itself.
      }
    }
    
  14. ==============================

    14.이것은 재귀가있는 계승의 아주 간단한 예입니다.

    이것은 재귀가있는 계승의 아주 간단한 예입니다.

    Factorials는 매우 쉬운 수학 개념입니다. 그들은 5와 같이 쓴다! 이것은 5 * 4 * 3 * 2 * 1을 의미합니다. 따라서 6! 720과 4입니다! 24입니다.

    function factorial($number) { 
    
        if ($number < 2) { 
            return 1; 
        } else { 
            return ($number * factorial($number-1)); 
        } 
    }
    

    이것이 당신에게 유용 할 수 있기를 바랍니다. :)

  15. ==============================

    15.간단한 예제 재귀 적 (Y)

    간단한 예제 재귀 적 (Y)

  16. ==============================

    16.Kaprekar 상수에 사용 된 재귀

    Kaprekar 상수에 사용 된 재귀

    function KaprekarsConstant($num, $count = 1) {
        $input = str_split($num);
        sort($input);
    
        $ascendingInput  = implode($input);
        $descendingInput = implode(array_reverse($input));
    
        $result = $ascendingInput > $descendingInput 
            ? $ascendingInput - $descendingInput 
            : $descendingInput - $ascendingInput;
    
        if ($result != 6174) {
            return KaprekarsConstant(sprintf('%04d', $result), $count + 1);
        }
    
        return $count;
    

    }

    이 함수는 계산 결과를 Kaprekars 상수에 도달 할 때까지 계속 호출합니다.이 상수에서는 계산이 수행 된 시간이 반환됩니다.

    / 편집 Kaprekars Constant를 모르는 사람들은 최소한 두 자리 숫자로 4 자리 숫자를 입력해야합니다.

  17. from https://stackoverflow.com/questions/2648968/what-in-laymans-terms-is-a-recursive-function-using-php by cc-by-sa and MIT license