• 代码意识流——花朵数问题(一)


    0.问题                          (黑体,15)

      一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数。              (宋体,15,Arial)
      例如:
      当N=3时,153就满足条件,因为 1^3 + 5^3 + 3^3 = 153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3表示5的3次方,也就是立方)。
      当N=4时,1634满足条件,因为 1^4 + 6^4 + 3^4 + 4^4 = 1634。
      当N=5时,92727满足条件。
      实际上,对N的每个取值,可能有多个数字满足条件。

      程序的任务是:求N=21时,所有满足条件的花朵数。注意:这个整数有21位,它的各个位数字的21次方之和正好等于这个数本身。如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。因为这个数字很大,请注意解法时间上的可行性。要求程序在3分钟内运行完毕。

    1.用C语言表达问题

    /*0_问题.h*/
    #ifndef WENTI_H
    #define WENTI_H 
    
        #define CESHI        //进行测试  
        //#define QIUJIE     //求解21位问题                              
        
        #ifdef CESHI             //测试
          #define JINZHI 10      //十进制 
          #define WEISHU 3       //3位花朵数   
          #define N      WEISHU  //幂次==位数 
        #endif //CESHI
        
        #ifdef QIUJIE            //求解            
          #define JINZHI 10      //十进制 
          #define WEISHU 21      //位数    
          #define N      WEISHU  //幂次==位数 
        #endif //QIUJIE
        
    #endif // WENTI_H
    

      编写代码首先要提出问题,理解问题,并用C语言表达问题。

      这里的符号常量就是C语言对问题的描述。尽管不可能完全描述,但却充分地表现了问题的特征。由于对问题进行了抽象,使得代码可以具有更广的适应范围。即不但适合求解21位花朵数,同样适合求解其他位数的花朵数问题;不但适合求解十进制问题,也适合其他进制问题。
      把问题中的常数写成符号常量同时也是为了测试的需要。没有人敢开一辆没有测试过的汽车,但是很奇怪,人们却敢于使用没有经过充分测试的软件,实际上后者往往更危险。

      测试的必要性还体现在,稍具规模的代码几乎绝对不可能一气呵成地一次性写正确,测试在这里实际上也是开发的有力助手。
      在开始写代码时并不清楚究竟有没有21位花朵数,如果有的话,同样也不清楚这个花朵数是多少。如果希望对自己的代码有点信心,那么这种信心只能来自测试。然而对21位花朵数的测试几乎没有可能,这时只能测试规模较小的同类问题。较小规模问题测试通过后,我们才能对较大的问题的解产生一些自信。

      这里的“#define CESHI        //进行测试”就如同一个开关一样,如果把CESHI改成QIUJIE,不用修改代码,只要重新编译,就可以得到求解21位问题的程序。

           
    2.开始求解

        首先写main()。由于在代码编写过程中涉及到测试,所以写了两个main()。   

       /*1_MAIN.c*/
    /*
      Name:花朵数问题 
      Author:键盘农夫  
      Date:2011,5,30 
      Description: 
    */
    
    #include "1_MAIN.h"
    
    #ifdef CESHI               //测试
    
       int main( void )
       {
       
          system("PAUSE");	
          return 0;
       }
    
    #endif //CESHI
    
    #ifdef QIUJIE              //求解
    
       int main( void )
       {
       
          system("PAUSE");	
          return 0;
       }
       
    #endif //QIUJIE
    

      与之对应的,还有一个 

    /*1_MAIN.h*/
    #ifndef MAIN_H
    #define MAIN_H 
    
       #include "0_问题.h"           
    /**************************类型定义**************************/ 
    
    
    /**************************函数原型**************************/ 
    
    
       #include <stdlib.h>                 //system()
        	
    #endif // MAIN_H
    

      这是联系“0_问题.h”和main()的纽带,同时也以备以后补充类型定义和函数原型。

      3.解决方案

      回顾问题不难发现,问题的全部要求可分为“求解”和“输出”两个步骤。

      搜索一下自己的数学知识,并没有什么神奇的定理对解决这个问题有所帮助。没办法,只好用最笨的办法——穷举。穷举只能在穷举的过程中对所枚举的各种可能进行验算,因此main()改写为

    #ifdef QIUJIE              //求解
    
       int main( void )
       {
          //求解:穷举<=>验算<=>记录结果 
          //输出 
          system("PAUSE");	
          return 0;
       }
       
    #endif //QIUJIE
    

      “记录结果”而不是立即输出的原因是问题要求“从小到大输出”。 

      编译通过,运行正常!收工。 

    4.完成第一个自定义函数框架的过程

      至少有四个函数需要写,首先从“穷举”入手。步骤:

      1.在main()中写出函数调用,qiongju();

      2.紧接着在原地描述这个函数的原型,void qiongju( void );

    #ifdef QIUJIE              //求解
    
       int main( void )
       {
          //求解:穷举<=>验算<=>记录结果 
          qiongju();//void qiongju( void );
          //输出 
          system("PAUSE");	
          return 0;
       }
       
    #endif //QIUJIE
    

      3.考虑这个函数定义的位置,由于这个函数可能比较复杂,所以把这个函数安排在另外一个源文件“2_穷举.c”中,添加“2_穷举.c”和“2_穷举.h”

      4.在"1_MAIN.h"中加入 #include "2_穷举.h" 预处理命令

      5.将main()中的qiongju()的函数原型移动到“2_穷举.h”的函数原型部分,并修改为
        extern void qiongju( void );

    /*2_穷举.h*/ 
    #ifndef QIONGJU_H
    #define QIONGJU_H 
    /**************************类型定义**************************/
    /**************************函数原型**************************/
     extern void qiongju( void );
    #endif // QIONGJU_H

      6.在"2_穷举.c"中写出空的qiongju()函数定义,顺便把main()中的一部分注释移过来

    /*2_穷举.c*/
    
    #include "2_穷举.h"
    
    extern void qiongju( void )
    {
    //<=>验算<=>记录结果
    }

      把 0_问题.h 中的 #define CESHI  中的CESHI改成QIUJIE,编译通过,运行正常!收工。

    (未完待续)

  • 相关阅读:
    RabbitMQ 工作图解
    RabbitMQ常用命令
    搭建 .Net RabbitMQ 开发环境
    不使用第三个变量交换两个变量的值
    WEB编程 入门简单 进阶难
    C# 字符串的长度问题
    C# 反射
    C# 拼接字符串的几种方式和性能
    ASP.NET MVC 教程汇总
    SSIS中循环遍历组件[Foreach Loop Container]
  • 原文地址:https://www.cnblogs.com/KBTiller/p/2060595.html
Copyright © 2020-2023  润新知