Use analogy to learn function recursion in programming (personal understanding is for reference only) (including the solution of the Tower of Hanoi problem)

Table of contents

1 Introduction

2. Recursive mathematical model

3. Related c syntax

4. Write the recursive mathematical model into a programming language

5. Use the analogy method to write the code of the actual problem into the form of function recursion

Example 1:

 Example 2:

6. Solving the Tower of Hanoi problem


1 Introduction

In the process of learning the functional recursive programming method, I found that learning the recursive method by analogy can help us apply the functional recursive method to code design in various programming problems.

In my opinion, the bottom-level thinking model of function recursion is: the recursive formula of the sequence of numbers in mathematics (the recursive formula of the sequence of numbers is the core of studying the properties of the sequence of numbers and the formula for general terms, and applying the recursive and iterative thinking model to code design , resulting in function recursion).

2. Recursive mathematical model

Now we arbitrarily give the first item of a sequence {An} and its recursion formula:

A1 == 1, An ==  2*A(n-1) +  1 (n>1)

There are many ways to solve the general term formula of the sequence in mathematics, one of which is called the iterative method: (the iterative method can be used to solve the general term of the sequence whose recursive formula is a first-order recursive formula) 

The so-called iterative method is to expand the items in the recursive formula item by item according to the recursive formula itself ( that is, from An to A1, and then return the result through calculation )

Next, we use the iterative method to try to find the general term formula of {An}: (n>1)

An=2*A(n-1) + 1 = 2*(2*A(n-2) +1) +1 = 2*(2*(2*A(n-3)+1)+1) +1=................................

In this way, it has been expanded to A1, and then the general term formula of An can be obtained through induction.

3. Related c syntax

We know that one of the things that computers are best at is doing the same form of calculation over and over again. However, in the iterative method, we start from An and expand it item by item according to the same recursive formula until A1. This algorithm is obviously very in line with the computer's thinking mode. In C language, we allow functions to nest themselves, namely:       

int  func(int n)    
{
    func(n); 
    return 0;
}

     

When calling a function, the function itself will call itself before returning the output and this process will be repeated continuously

In order to allow the function to finally return the output, we need to conditionally constrain the value passed in by the function and the value passed in each time must approach the constraint condition, such as:

   


int func(int n) 
{
     if(n>=1)
     { 
        func(n-1);
     }
     else
     {
        return0;
     }
}

 In this way, the function will pass the value inwards layer by layer n times and then return the output layer by layer. 

4. Write the recursive mathematical model into a programming language

Now we want the computer to help us find the value of any item in the sequence {An}. It is required to design a function int func(int) to input a positive integer n as a formal parameter, and the function will return the value of An.

Idea guide: {An}'s recursive formula An= 2*A(n-1) + 1    

If An in the recursive formula is equivalent to func(n) in the code, then A(n-1) is equivalent to func(n-1) in the code

Combining the idea of ​​iterative method to find the general term and related C syntax, the following code can be written

int func(n)
{
   if(n>1)                  //递推公式的成立条件
   {
      return 2*func(n-1)+1; //数列的递推公式
   } 
   else
   {
      return 1 ;            // 数列首项为以1
   }
}

When the computer executes this code, it will automatically help us complete the iterative process. ( In this process, the value of the function is decremented and the value is passed inward until the integer 1 is passed inward for the last time ["pass" process], and then from the innermost function Start to return the value layer by layer ["return" process] and finally get the result ) ( the recursion formula determines the method of function recursion and the function structure, and the first item determines the return value node )

After further thinking, we can know that given any sequence of numbers, as long as we know its first item and the recursion formula, we can write the code in the same form as the above code to find the value of any item.

5. Use the analogy method to write the code of the actual problem into the form of function recursion

Example 1:

Question: Design a function to replace the library function strlen(), which is used to find the length of the string. The formal parameter is char* type and the return value is int type.

Our custom function is named restrlen() 

Suppose we ask for the length of the string "bite". Create an array of strings char arr[]="bite".

First abstract an item of a sequence restrlen("bite")

We can get the recurrence relation restrlen("bite") = restrlen("ite") + 1

In view of the requirements of the title, we can only pass the address of arr, which is the letter b, into the function when finding the length of "bite"

Then restrlen("bite") is equivalent to restrlen(arr), similarly, restrlen("ite") is equivalent to restrlen(arr+1)

So the recurrence relationship becomes restrlen(arr)=restrlen(arr+1) +1  

The first item in this problem is restrlen(arr+x) = 0, x is an integer and satisfies *(arr+x)="\0" So we have the following code:

int restrlen(char* x)
{
    if(*(x+1)!=0)                  //类似于递推公式成立条件
    {
         return restrlen(x+1) +1;  //类似于数列递推公式
    }
    else
    {
         return 0;                 //类似于首项
    }
}

 Example 2:

Question: Design a function. When an integer is input, the function will output and print out the digits of each decimal place of the integer in sequence. For example: input 123 and print 1 2 3

Let's name the function prt, take the input 123 as an example

To print out 1 first, then 1 must be output in the innermost function (the return value is from the inside out)

First abstract the item prt(123) of a sequence, the previous item can be abstracted as prt(12)

Then we can abstract the recursive formula prt(123)= prt(12) + "printf("%d",123 %10)

If n in the sequence is equivalent to "123", then n-1 is equivalent to "123/10"

When the input value is divided by 10 and is equal to 0, the "first item" (analogous sense) is obtained. The value of the "first item" is 0

Since the output method of the function is printout, there is no need to return a value (note that the value must be passed to the inner layer before printing out)

void Print(int n)
{
   if(n/10!=0)
   {
       Print(n/10);
       printf("%d",n%10);
   }
}

6. Solving the Tower of Hanoi problem

First analyze the Tower of Hanoi problem from a mathematical point of view: Now suppose that the total number of times to move the n disks on the A-pillar to the C-pillar by means of the B-pillar is Xn. Obviously we can get the sequence {Xn}, where
n >=1 Next, let’s study the recursive formula of the sequence, that is, try to study the relationship between Xn and Xn-1. By
analyzing the problem from the special to the general method, we can analyze the following rules;

  1. In order to move n discs from column A to column C by means of column B, we have to go through a step: move the largest disc on column A to column C.
  2. Before completing the steps described in 1. Analysis, there must be only one largest disc left on the A-pillar, the C-pillar must be empty, and there are n-1 discs on the B-pillar
  3. Therefore, we must complete another step after the game starts: move the n-1 discs on the A column to the B column with the help of the C column.
  4. We call the steps described in analysis 3. as: the first step (we don’t need to care about how this step is carried out specifically) and call the steps described in analysis 1. as: the second step
  5. Obviously, if Xn represents the total number of times the disk needs to be moved in the Tower of Hanoi problem with n disks, then the total number of times the disk needs to be moved in the first step is Xn-1 times
  6. At the same time, the total number of times the second step needs to move the disk is 1 time
  7. After completing the first and second steps, we can ignore the largest disc on the C-pillar and continue to analyze the next step
  8. Next, we only need to move the n-1 discs on B to the C pillar with the help of the A pillar. We call this step the third step (we also don’t care about how this step is carried out)
  9. Obviously, the total number of times to move the disk to complete the third step is also Xn-1 times

Through the above analysis, we can draw a conclusion: In order to solve the Hanoi Tower problem with n (n>1) disks, we need to go through the following three steps (set the total number of moving disks as Xn) (here A is the starting column, B is the transition column, C is the target column)
The first step: move n - 1 discs on the A column to the B column with the help of the C column (moving Xn-1 times) (here A is the starting column, C is the transition column, B is the target column)
Step 2: Move the largest remaining disc on column A to column C (move 1 time)   
Step 3: Move n - 1 discs on column B with the help of column A Move to column C (move Xn-1 times) (here B is the starting column, A is the transition column, and C is the target column)
to get the recursive formula of the sequence (n>1):      

          Xn       =     ( Xn-1 )   +   (1)   +   (Xn-1)
  /*移动圆盘的总次数*/    /*第一步骤*/ /*第二步骤*/   /*第三步骤*/

When n==1, obviously we only need to perform the second step once, that is, X1==1

Using the above mathematical conclusions, let us try to solve the c language programming problem of the Tower of Hanoi. The
programming requirement is: design a function to input the formal parameter n as the initial disc total number function (for example, when n == 3 is input) and print the output in the following form (In this form, the user is told each specific disc movement step to solve the Hanoi Tower problem of n discs)

               A-->C        
               A-->B
               C-->B
               A-->C
               B-->A
               B-->C
               A-->B

According to the analysis of the mathematical recursion formula, we can preliminarily conclude: in the Tower of Hanoi function, we have two steps of decrementing the value to the inner function (the "passing" step), and there is a step of moving a single disc in the middle.
Obviously The step of moving a single disc in the middle can be used as the recursive return output node of our function (that is, the "return" step from the innermost function to the outer function to return the output), so we can get the following function recursion framework
:

    void Hanoi(int n)     //总过程:将A柱上n个圆盘借助B柱移动到C柱
    {
        Hanoi(n - 1);     /*第一步骤(函数向内递值 即“递”的步骤)*/
        printf() ;        /*第二步骤(该步骤具体实行打印输出 即"归"的步骤)*/
        Hanoi(n - 1);     /*第三步骤(函数再一次向内递值)*/
    }

The above is the basic recursive framework based on the mathematical analysis of the Tower of Hanoi problem.
However, in order to combine the "outermost function's process of "moving n discs on A column to C column by means of B column"" and "the first inner The process of "moving n - 1 discs on column A to column B via column C" of the layer function and "moving n - 1 discs on column B to column B via column A" of the second inner function To distinguish the three,
we must introduce three character parameters to represent the three columns of ABC and distinguish the three analyzed in the previous sentence through the difference in the arrangement order of these three character parameters in the function parentheses (). A process
, so we can further fill in the function recursion framework and give the restriction of the function inward recursion to complete the code design

int count = 0;
void Hanoii(char a, char b, char c, int n)          
{
    if (n >= 1)
    {  
        Hanoii(a, c, b, n - 1);                     
        count++;
        printf("%d.  %c-->%c\n", count, a, c);      
        Hanoii(b, a, c, n - 1);                      
                                                    
    }
}
int main()
{
    char x = 'A';
    char y = 'B';
    char z = 'C';
    int k = 0;
    scanf("%d", &k);
    Hanoii(x, y, z, k);
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_73470348/article/details/126722259