《C#零基础入门之百识百例》(三十七)方法递归 -- 李白打酒

Posted 陈言必行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《C#零基础入门之百识百例》(三十七)方法递归 -- 李白打酒相关的知识,希望对你有一定的参考价值。

前言

本文属于C#零基础入门之百识百例系列文章。此系列文章旨在为学习C#语言的童鞋提供一套系统的学习路径。此系列文章都会通过【知识点】【练习题】的形式呈现。有任何问题,你都可以通过评论私信等方式找到我,我会一对一解答你的问题。


系列文章目录:
《C#零基础入门之百识百例》 目录文章传送门


一,方法递归

1.1 释义说明

一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

方法直接或间接的调用自己,称为递归调用。

递归会产生很优雅的代码。

C#允许方法实现直接递归调用和间接递归调用。

递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

1.2 程序示例

使用递归求解问题,通常可以将一个比较大的问题层层转化为一个与原问题相类似的、规模较小的问题进行求解,最终实现对原问题的求解。

使用递归时一定要注意必须具备让递归结束的条件,否则很容易造成死循环。

示例:将用户输入的字符串逆序输出,字符串以’!’结束。

class Program

    static void Main(string[] args)
    
        ReverseStr();
        Console.ReadKey();
    
    
    static void ReverseStr()
    
        char c = Convert.ToChar(Console.Read());
       
        if (c == '!')  // 检测到是!则退出
            return;
        else           // 递归调用         
            ReverseStr();
            
        Console.Write(c);
       



二,实例练习 – 李白打酒

2.1 题目描述

一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。

2.2 问题分析

设李白走一步就遇到花或店,则由题意可知:店5次,花10次,最后一次是花并且刚好喝完酒,则总步数为(5+10)-1 = 14次。

走一步逻辑:

  • 下一步遇到花:步数-1,酒-1,店不变,花-1
  • 下一步遇到店:步数-1,酒*2,店-1, 花不变

2.3 参考代码

class Program

    // 记录符合条件的次数
    private static int Count = 0;
    static void Main(string[] args)
    
        LiBai(14, 2, 5, 10);
        Console.WriteLine("符合题意的条件个数:" + Count);
        Console.ReadKey();
    
    
    /// <summary>
    /// 李白打酒
    /// </summary>
    /// <param name="step">表示遇到花和店的次数</param>
    /// <param name="jiu">表示还剩多少斗酒</param>
    /// <param name="dian">表示还剩多少次店</param>
    /// <param name="hua">表示还剩多少次花</param>
    private static void LiBai(int step, int jiu, int dian, int hua)
    
        //递归出口 --> 无步数 或 无酒 或 无店 或 无花(最后一次是花,则hua>=1)
        if (step < 0 || jiu < 0 || dian < 0 || hua < 1)
        
            //Console.WriteLine(step + "," + jiu + "," + dian + "," + hua);
            return;
        
        //根据题意酒剩1斗,最后一次是花,则条件成立(即最后一次遇到花,把酒喝光)
        if (step == 0 && jiu == 1 && dian == 0 && hua == 1)
        
            // 返回次数 +1
            Count++;
            return;
        

        // 遇到花:步数-1,酒-1,店不变,花-1
        LiBai(step - 1, jiu - 1, dian, hua - 1);
        // 遇到店:步数-1,酒*2,店-1, 花不变
        LiBai(step - 1, jiu * 2, dian - 1, hua);           
    

以上是关于《C#零基础入门之百识百例》(三十七)方法递归 -- 李白打酒的主要内容,如果未能解决你的问题,请参考以下文章

《C#零基础入门之百识百例》(六十七)枚举常用方法 -- 使用示例

《C#零基础入门之百识百例》(三十六)方法重载 -- 回文数

《C#零基础入门之百识百例》(三十五)方法返回 -- 自守数

《C#零基础入门之百识百例》(三十一)方法定义 -- 猜数游戏

《C#零基础入门之百识百例》(五十七)密封类 -- 任意年月日历输出

《C#零基础入门之百识百例》(三十二)方法参数 -- 引用&输出参数 -- 两数交换