📌  相关文章
📜  以Hofstadter男性和女性序列为例的相互递归

📅  最后修改于: 2021-04-27 17:42:02             🧑  作者: Mango

相互递归是变异递归。如果第一个函数对第二个函数进行递归调用,而第二个函数又调用第一个函数,则将两个函数称为相互递归。

在软件开发中,此概念以循环依赖关系使用,循环依赖关系是两个或多个直接或间接依赖彼此以函数运行的模块之间的关系。这样的模块也称为相互递归。

相互递归的一个很好的例子是实现Hofstadter序列。

霍夫斯塔德序列

在数学中,霍夫斯塔特序列是由非线性递归关系定义的一组相关整数序列的成员。在此示例中,我们将重点介绍霍夫施塔特女性和男性序列:

F ( 0 ) = 1M ( 0 ) = 0F ( n ) = n - M ( F ( n - 1 ) ), n > 0M ( n ) = n - F ( M ( n - 1 ) ), n > 0.

C++
// C++ program to implement Hofstader Sequence
// using mutual recursion
#include 
using namespace std;
  
int hofstaderFemale(int);
int hofstaderMale(int);
  
// Female function
int hofstaderFemale(int n)
{
    if (n < 0)
        return 0;
    else
        if (n == 0)
            return 1;
        else
            return (n - hofstaderFemale(n - 1));
}
  
// Male function
int hofstaderMale(int n)
{
    if (n < 0)
        return 0;
    else
        if (n == 0)
            return 0;
        else
            return (n - hofstaderMale(n - 1));
}
  
// Driver Code
int main()
{
    int i;
    cout << "F: ";
    for (i = 0; i < 20; i++) 
        cout << hofstaderFemale(i) << " ";
      
    cout << "\n";
  
    cout << "M: ";
    for (i = 0; i < 20; i++) 
        cout << hofstaderMale(i)<< " "; 
  
    return 0;
}
  
// This code is contributed by shubhamsingh10


C
// C program to implement Hofstader Sequence
// using mutual recursion
#include 
  
int hofstaderFemale(int);
int hofstaderMale(int);
  
// Female function
int hofstaderFemale(int n)
{
    if (n < 0)
        return;
    else
        return (n == 0) ? 1 : n - hofstaderFemale(n - 1);
}
  
// Male function
int hofstaderMale(int n)
{
    if (n < 0)
        return;
    else
        return (n == 0) ? 0 : n - hofstaderMale(n - 1);
}
  
// hard coded driver function to run the program
int main()
{
    int i;
    printf("F: ");
    for (i = 0; i < 20; i++) 
        printf("%d ", hofstaderFemale(i));
      
    printf("\n");
  
    printf("M: ");
    for (i = 0; i < 20; i++) 
        printf("%d ", hofstaderMale(i));    
  
    return 0;
}


Java
// Java program to implement Hofstader 
// Sequence using mutual recursion
import java .io.*;
  
class GFG {
      
    // Female function
    static int hofstaderFemale(int n)
    {
        if (n < 0)
            return 0;
        else
            return (n == 0) ? 1 : n - 
            hofstaderFemale(n - 1);
    }
      
    // Male function
    static int hofstaderMale(int n)
    {
        if (n < 0)
            return 0;
        else
            return (n == 0) ? 0 : n - 
                hofstaderMale(n - 1);
    }
  
    // Driver Code
    static public void main (String[] args)
    {
        int i;
        System.out.print("F: ");
        for (i = 0; i < 20; i++) 
            System.out.print(hofstaderFemale(i) 
                                        + " ");
          
        System.out.println();
      
        System.out.print("M: ");
        for (i = 0; i < 20; i++) 
            System.out.print(hofstaderMale(i)
                                      + " "); 
    }
}
  
// This code is contributed by anuj_67.


Python3
# Python program to implement 
# Hofstader Sequence using 
# mutual recursion
  
# Female function
def hofstaderFemale(n):
    if n < 0:
        return;
    else:
        val = 1 if n == 0 else (
                   n - hofstaderFemale(n - 1))
        return val
  
# Male function
def hofstaderMale(n):
    if n < 0:
        return;
    else:
        val = 0 if n == 0 else (
                   n - hofstaderMale(n - 1))
        return val
  
# Driver code
print("F:", end = " ")
for i in range(0, 20):
    print(hofstaderFemale(i), end = " ")
  
print("\n")
print("M:", end = " ")
for i in range(0, 20):
    print(hofstaderMale(i), end = " ")
  
# This code is contributed
# by Shantanu Sharma


C#
// C# program to implement Hofstader 
// Sequence using mutual recursion
using System;
  
class GFG {
      
    // Female function
    static int hofstaderFemale(int n)
    {
        if (n < 0)
            return 0;
        else
            return (n == 0) ? 1 : n - 
               hofstaderFemale(n - 1);
    }
      
    // Male function
    static int hofstaderMale(int n)
    {
        if (n < 0)
            return 0;
        else
            return (n == 0) ? 0 : n - 
                 hofstaderMale(n - 1);
    }
  
    // Driver Code
    static public void Main ()
    {
        int i;
        Console.WriteLine("F: ");
        for (i = 0; i < 20; i++) 
            Console.Write(hofstaderFemale(i) + " ");
          
        Console.WriteLine();
      
        Console.WriteLine("M: ");
        for (i = 0; i < 20; i++) 
            Console.Write(hofstaderMale(i) + " "); 
    }
}
  
// This code is contributed by Ajit.


PHP


Output:
F: 1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 
M: 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 

循环依赖/相互递归的缺点:

  1. 当一个模块中的一小部分本地更改扩展到其他模块并产生有害的全局影响时,循环依赖项可能会导致多米诺效应
  2. 循环依赖关系还可能导致无限递归或其他意外失败。
  3. 循环依赖关系还可以通过阻止某些非常原始的自动垃圾收集器(使用引用计数的垃圾收集器)释放未使用的对象来导致内存泄漏。

参考:维基百科