zoukankan      html  css  js  c++  java
  • 数据结构和算法设计专题之---24点游戏(穷举法和递归法)

    一个简单的24点程序

           下面本文将通过两个题目实例,分别给出用递归方法和循环方法的解决方案以及解题思路,便于读者更好地掌握两种方法。首先是一个简单的计算24点的问题(为了简化问题,我们假设只使用求和计算方法):

    19中任选四个数字(数字可以有重复),使四个数字的和刚好是24

     

    题目很简单,数字都是个位数,可以重复且之用加法,循环算法的核心就是使用四重循环穷举所有的数字组合,对每一个数字组合进行求和,判断是否是24。使用循环的版本可能是这个样子:

        8 const unsigned int NUMBER_COUNT = 4; //9

        9 const int NUM_MIN_VALUE = 1;

       10 const int NUM_MAX_VALUE = 9;

       11 const unsigned int FULL_NUMBER_VALUE = 24;//45;

       40 void PrintAllSResult(void)

       41 {

       42     int i,j,k,l;

       43     int numbers[NUMBER_COUNT] = { 0 };

       44 

       45     for(= NUM_MIN_VALUE; i <= NUM_MAX_VALUE; i++)

       46     {

       47         numbers[0] = i; /*确定第一个数字*/

       48         for(= NUM_MIN_VALUE; j <= NUM_MAX_VALUE; j++)

       49         {

       50             numbers[1] = j;  /*确定第二个数字*/

       51             for(= NUM_MIN_VALUE; k <= NUM_MAX_VALUE; k++)

       52             {

       53                 numbers[2] = k; /*确定第三个数字*/

       54                 for(= NUM_MIN_VALUE; l <= NUM_MAX_VALUE; l++)

       55                 {

       56                     numbers[3] = l; /*确定第四个数字*/

       57                     if(CalcNumbersSum(numbers, NUMBER_COUNT) ==FULL_NUMBER_VALUE)

       58                     {

       59                         PrintNumbers(numbers, NUMBER_COUNT);

       60                     }

       61                 }

       62             }

       63         }

       64     }

       65 }

    这个PrintAllSResult()函数看起来中规中矩,但是本人的编码习惯很少在一个函数中使用超过两重的循环,更何况,如果题目修改一下,改成9个数字求和是45的组合序列,就要使用9重循环,这将使PrintAllSResult()函数变成臭不可闻的垃圾代码。

             现在看看如何用递归方法解决这个问题。递归方法的解题思路就是对题目规模进行分解,将四个数字的求和变成三个数字的求和,两个数字的求和,当最终变成一个数字时,就达到了递归终止条件。这个题目的递归解法非常优雅:

       67 void EnumNumbers(int *numbers, int level, int total)

       68 {

       69     int i;

       70 

       71     for(= NUM_MIN_VALUE; i <= NUM_MAX_VALUE; i++)

       72     {

       73         numbers[level] = i;

       74         if(level == (NUMBER_COUNT - 1))

       75         {

       76             if(== total)

       77             {

       78                 PrintNumbers(numbers, NUMBER_COUNT);

       79             }

       80         }

       81         else

       82         {

       83             EnumNumbers(numbers, level + 1, total - i);

       84         }

       85     }

       86 }

       87 

       88 void PrintAllSResult2(void)

       89 {

       90     int numbers[NUMBER_COUNT] = { 0 };

       91 

       92     EnumNumbers(numbers, 0, FULL_NUMBER_VALUE);

       93 }

    如果题目改成“9个数字求和是45的组合序列”,只需将NUMBER_COUNT的值改成9FULL_NUMBER_VALUE的值改成45即可,算法主体部分不需做任何修改。

  • 相关阅读:
    android中的一个圆角图片
    android中一个评分的控件
    C++ primer(第五版)中需要复习第二遍的知识点记录
    在ubuntu18.04上交叉编译opencv2.4.9
    C6748和音频ADC连接时候的TDM以及I2S格式问题
    C6748的启动方式问题
    AK5703的ALC
    cool edit工具介绍及使用
    CCS编译环境及TI仿真器的使用
    把YUV转化成opencv中的Mat格式的两行代码备份
  • 原文地址:https://www.cnblogs.com/roccheung/p/5797340.html
Copyright © 2011-2022 走看看