zoukankan      html  css  js  c++  java
  • 递归的Fibonacci在数羊

    一、由数羊引起的

    有一道经典的面试题是这样的。

    题目:一头母羊的寿命是5年,它会在第2年底和第4年底各生下一头母羊,第5年底死去,
    问一开始农场有1头母羊,N年后,农场会有多少只母羊?

    (假设没有公羊也会生羊,而且只只生母羊,不要较真 - -!)

    乍一看不知所云,其实慢慢分析so easy!


    思路:
    年数      羊的个数      备注
    1            1             1只羊
    2            2=1+1      生1只
    3            2             不生
    4            4=2+2      第1只在第4年生,第2只在第2年生
    5            3=4-1       第1只样死去
    6            6=3+3      第2只在4年生,第3只在第2年生,第4只在第2年生
    7            5=6-1       第2只样死去
    8            10=5+5     第3只在第4年生,第4只在第4年生,
    9            8=10-2     第3只和第4只死去
    10          16=8+8     继续生...
    规律:奇数年是1 2 3 5 8 的斐波那契数列
          偶数年是2 4 6 10 16的斐波那契数列

    所以我们首先得了解Fibonacci数列。

    二、Fibonacci数列

    【题目】一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。

    /// <summary>
    /// 一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现
    /// </summary>
    /// <param name="pos">第几位</param>
    /// <returns>返回该位置处的数字</returns>
    public int Fib(int pos)
    {
        if (pos <= 0)
        {
            return 0;
        }
        if (pos == 1)
        {
            return 1;
        }
        int result = Fib(pos - 1) + Fib(pos - 2);
        return result;
    }
    

      


    我们还可以将递归改为非递归。利用数组就可实现。比方说:

    /// <summary> 
    /// 非递归算法计算斐波那契数,速度要比递归快 
    /// </summary> 
    /// <param name="pos">第几位</param> 
    /// <returns>返回该位置处的数字</returns> 
    public int GetNumAtPos(int pos) 
    { 
        int result = 0; 
        int[] arr = new int[1000 * 1000];
    
        arr[0] = 1; 
        arr[1] = 1;
    
        for (int i = 2; i < pos; i++) 
        { 
            arr[i] = arr[i - 2] + arr[i - 1]; 
        }
    
        result = arr[pos - 1];
    
        return result; 
    } 
    

      

    三、农场养羊问题

    了解了Fibonacci数列之后,我们继续回到数羊的问题上。根据分析的思路可以写出如下一种实现方式:

    public class Fibonacci 
    { 
        /// <summary> 
        /// 题目:一头母羊的寿命是5年,它会在第2年底和第4年底各生下一头母羊,第5年底死去, 
        /// 问一开始农场有1头母羊,N年后,农场会有多少只母羊?(假设只生母羊,不要较真 - -!) 
        /// </summary> 
        /// <remarks> 
        /// 思路: 
        ///年数      羊的个数      备注 
        ///1            1            1只羊 
        ///2            2=1+1        生1只 
        ///3            2            不生 
        ///4            4=2+2        第1只在第4年生,第2只在第2年生 
        ///5            3=4-1        第1只样死去 
        ///6            6=3+3        第2只在4年生,第3只在第2年生,第4只在第2年生 
        ///7            5=6-1        第2只样死去 
        ///8            10=5+5        第3只在第4年生,第4只在第4年生, 
        ///9            8=10-2        第3只和第4只死去 
        ///10            16=8+8        继续生... 
        ///规律:奇数年是1 2 3 5 8 的斐波那契数列 
        ///      偶数年是2 4 6 10 16的斐波那契数列 
        /// </remarks> 
        /// <param name="year"></param> 
        /// <returns></returns> 
        public int CountSheep(int year) 
        { 
            int result = 0; 
            // 奇数年 
            if (year%2==1) 
            { 
                year = (year + 1) / 2; // 折半 
                result = EvenSum(year); 
                return result; 
            } 
            // 偶数年 
            if (year%2==0) 
            { 
                year = year / 2; // 折半 
                result = OddSum(year); 
                return result; 
            } 
            return result; 
        }
    
        /// <summary> 
        /// 奇数年的Fibonacci数 
        /// </summary> 
        /// <param name="year">第几年</param> 
        /// <returns>羊的个数</returns> 
        private int EvenSum(int year) 
        { 
            int num = 0; 
            if (year <= 0) 
            { 
                return 0; 
            } 
            if (year==1) 
            { 
                return 1; 
            } 
            if (year==2) 
            { 
                return 2; 
            }
    
            num = EvenSum(year - 1) + EvenSum(year - 2);
    
            return num; 
        }
    
        /// <summary> 
        /// 偶数年的Fibonacci数 
        /// </summary> 
        /// <param name="year">第几年</param> 
        /// <returns>羊的个数</returns> 
        private int OddSum(int year) 
        { 
            int num = 0; 
            if (year<=0) 
            { 
                return 0; 
            } 
            if (year==1) 
            { 
                return 2; 
            } 
            if (year==2) 
            { 
                return 4; 
            } 
            num = OddSum(year - 1) + OddSum(year - 2); 
            return num; 
        } 
    }
    

      

    测试方法如下:

    static void Main(string[] args) 
    { 
    	int result = 0;
    
    	// 斐波那契方法测试 
    	Fibonacci fib = new Fibonacci(); 
    	//result = fib.Fib(30);
    
    	// 非递归数组方法测试 
    	//result = fib.GetNumAtPos(50);
    
    	// 数羊测试 
    	for (int i = 1; i <= 12; i++) 
    	{ 
    		result = fib.CountSheep(i); 
    		Console.WriteLine("第 " + i + " 年羊的个数为:" + result); 
    	}
    
    	
    	Console.ReadLine(); 
    }
    

      

    运行效果如下:

  • 相关阅读:
    linux编译C
    Windows下ARP协议的工作原理简介
    窥探QQ基础数据库架构演变史
    JAVA培训—线程同步--卖票问题
    SQLite、MySQL和PostgreSQL 三种关系数据库哪个好?
    再论谭浩强《C语言程序设计》
    JPG加入RAR文件原理详解
    如何区分一个程序员是“老手“还是“新手“?
    AutoITx3.DLL所有函数及说明
    windows索引服务
  • 原文地址:https://www.cnblogs.com/fanyong/p/FibonacciCountSheep.html
Copyright © 2011-2022 走看看