Lesson Three: Three examples of recursion

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Overview

This paper explains the mechanism of recursive operation, and explains the simple recursion condition. From the point of view of program design, recursion is actually an indispensable method of modern programming, and for many problems, recursion may be a more suitable solution. But how to design recursion needs to design or solve the recursive formula, in order to be converted to recursion, the emphasis is on design recurrence formula. The following sections explain three examples, one is known to the Hanoi, one is to arrange, one is to seek integer division, focusing on how to design a recursive formula. Please see my github for more detailed code.

Example 1: Hanoi

Hanoi is a necessary part of children's shoes, which is bound to be: Always keep the small disc on top of the big disk, from one pillar to another pillar, in the middle can use a pillar, 1 shows:


Figure 1: Hanoi, excerpt from Wikipedia

Intuitively this should be a recursive problem, but how to design a recursive formula is a lot of children's shoes feel more headache problem. The essence of design recursion formula is formalization, looking for the problem of size n and the relationship between the problem of size n-1 (or less than n-1).

So how to design recursion formula for Hannotalay? First of all the objects involved in the formal description, assuming that three pillars are numbered a, B, C, the number of disks in the Hanoi Tower is n, the initial n disk in a, solve the problem is: the use of B, a in the N disk moved to C, and to moderate keep small disk can not be under the market. Formalized as: F (n, A, B, C); The next step is to analyze the process, which must be described as follows (it is important to think of a way to move the largest disc in the bottom of a to the C disk):

    • The n-1 disk in a is placed on the B plate with the help of the C disk, and its corresponding problem is formalized to f (n-1, A, C, b).
    • Place the bottom disc of a in C;
    • The n-1 disk in B is placed on C with a, and its corresponding problem is formalized as f (n-1, B, A, C).

Of course, this is not the end, you must also define the termination condition, otherwise it is infinite loop, the termination condition of this problem is: when N=1, move directly, do not catch the middle pillar. The corresponding Golang program is:
func Hannoi(n int, first, second, third string){ if n == 1{ fmt.Println(first, "->", third) }else{ Hannoi(n - 1, first, third, second) fmt.Println(first, "->", third) Hannoi(n - 1, second, first, third) }}

Example 2: Permutation

The problem is as follows:

Design an algorithm that implements the full arrangement of {R1,R2,..., rn}

This problem is relative to Example 1, which is difficult (in general, algorithms involving pure digital game classes can be difficult). In the first example, suppose that the arrangement of {1, 2, 3} is required, and what is our general logic of thinking. Usually (not genius), it should be:

123, 132 | 213, 231 | 312, 321, so the thinking will be more structured

That is, assuming that the set of numbers is {R1,R2,..., rn}, which requires the arrangement F (s) of the N-Number set S, you can first take out one of the RM, and then place RM in the remainder of the n-1 number of permutations F (s-{rm}), the RM is in the front row of all the columns played If you take M = 1, 2, ... n, all the permutations are listed. The description itself is recursive and the termination condition is: When the element in S is 1 o'clock, it returns the number directly (a number has only one permutation). The corresponding Golang program is as follows:
func Permutation(input string) []string { ret := make([]string, 0) if len(input) == 1 { ret = append(ret, input) return ret } for idx, v := range input { var left string = "" if idx == 0 { left = input[1:] } else { pre := input[:idx] post := input[idx+1:] left = strings.Join([]string{pre, post}, "") } leftPermutaions := Permutation(left) for _, per := range leftPermutaions { oneUnit := strings.Join([]string{string(v), per}, "") ret = append(ret, oneUnit) } } return ret}

Example 3: Calculating the division of integers

The problem of number partitioning is described as:

For any integer n, the number of its partitions, such as n=5, is divided into:

  • 5
  • 4 + 1
  • 3 + 2
  • 3 + 1 + 1
  • 2 + 2 + 1
  • 2 + 1 + 1 + 1
  • 1 + 1 + 1 + 1 + 1
    That is, when n=5, there are 7 kinds of division

Phase ratio 1 and Example 2, the problem is more difficult, it is difficult to directly identify the recurrence of the relationship, and there seems to be no particularly good way. If f (n) is defined as the number of divisions of integer n and f (n-1) is the number of n-1, it is difficult to directly identify the relationship between the two. If we look at the above-mentioned 5 division of the process, it seems that there are some rules, each division of the largest number from large to small in the row. What is the relationship between setting the largest number in each division to M, and using P (n, m) to denote the maximum number of divisions in which the integer n is divided by the number of M?

    • A) When n=m, there are clearly only 1 divisions
    • b) When 1 < m < N, two scenarios can be considered:

      • Case 1: First take out m as the largest number in the division, then the number of integer n-m (the largest number in the division can not exceed M, think about why) that is the number of such cases, p (n-m, M)
      • Case 2: Consider the maximum number of m-1 in the division, the number of such cases is: P (n, m-1).

        So, b) under Scene P (n, m) = P (n, m-1) + p (n-m, M)

    • c) when M > N, it is obvious that this situation occurs in B) In case 1 continues to execute, according to the semantics: N of the number of partitions, and the maximum number of divisions can not exceed m (in this case, the condition is clearly established), therefore, the number of divisions of this case is P (n, N)

    • D) when m = 1 o'clock, P (n, m) = 1, clearly established.

The corresponding Golang is called:
// 求整数的不同划分数, 要求n > 0// n: 待划分的整数,m: 划分中最大的整数func DivideInteger(n, m int) int { if n <= 0 { return 0 } if m == 1 { return 1 } if n < m { return DivideInteger(n, n) } if n == m { return 1 + DivideInteger(n, n - 1) } if n > m && n > 1 && m > 1{ return DivideInteger(n, m - 1) + DivideInteger(n - m, m) } // 当前面的条件都不成立时,程序能执行到这里,必然是m为1的时候,显然,对于任意的n,必然只有一种分法,即都为1 return 0}

Summarize

Although recursion is very common, and its logic is simple in general business processing, it does not mean that it is easy to find recursive patterns in recursion. Especially in the big data today, the digital solution has become a very important part of data mining, machine learning, how to quickly find the corresponding formula of recursive formula needs a certain mathematical basis and regular thinking exercise. In short, recursive formulas are the core of recursion.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.