当前位置: 首页 > news >正文

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

本文前一部分的链接
http://www.cnblogs.com/KBTiller/archive/2011/06/07/2074344.html

21.记录结果
   由于无法保证输出的结果有序,所以只能把计算结果存储起来,待全部计算完毕再输出。
   事先也无法知道花朵数的个数,所以链表是比较适宜的存储方式。这种方案同时很容易保证保证有序存储。
   可以考虑用返回值的办法返回这个链表的head,也可以在main()中定义这个head,向qiongju()和xunhuan()传递&head。但是不难发现这两种方案参数总是要经历一系列无谓的传递,由于嵌套深度较深,求出结果的位置距离main()很远,所以不考虑这样的方案。代之以外部变量方案。
   首先在xunhuan()中写出函数调用语句及函数原型

   jilu( & he ); // void jilu( DASHU * );   //<=>记录结果

   把// void jilu( DASHU * ); 移动到"2_穷举.h"中,此后"2_穷举.c"变为

/*2_穷举.c*/

#include "2_穷举.h"
#include "0_问题.h"

typedef unsigned int SHUZI_GESHU[JINZHI];
//SHUZI_GESHU[d]存储数字d的个数 

typedef DASHU SHUJUBIAO[JINZHI-1][WEISHU + 1];
//0*(JINZHI-1)^N  1*(JINZHI-1)^N ……WEISHU*(JINZHI-1)^N
//0*(JINZHI-2)^N  1*(JINZHI-2)^N ……WEISHU*(JINZHI-1)^N
//……
//0*(1)^N         1*(1)^N        ……WEISHU*(1)^N

static void xunhuan(const int , const int , DASHU (*)[WEISHU + 1] ) ;

static void jianli_sjb ( SHUJUBIAO * * ); //建立数据表

static SF wenhe( SHUZI_GESHU * const , const DASHU * const);

static SF wenhe( SHUZI_GESHU * const p_sz_gs , 
                 const DASHU * const p_he )
{
   int sz_gs_he[JINZHI] = { 0 }; //和中各数字的个数

   if(  chaoguo_W(p_he) == SHI  // 超过W位 || 不足W位  
     || buzu_W   (p_he) == SHI ){  
     return FOU ;
   } 

   qiu_sz_gs( &sz_gs_he , p_he ); // 求和中各数字的个数
   
   if ( memcmp ( sz_gs_he , *p_sz_gs , sizeof sz_gs_he )==0 ){
      return SHI ;
   }
   return FOU ;

}

//建立数据表 
static void jianli_sjb ( SHUJUBIAO * * p_p_sjb )
{
   if( (* p_p_sjb = malloc(sizeof(SHUJUBIAO)) ) == NULL ){ //#include <stdlib.h> 
      exit(!EXIT_SUCCESS);
   }

   {  
      int i , j  ;
      for( i = 0 ; i < JINZHI - 1 ; i ++){
         ds_fuzhi( *( * * p_p_sjb + i ) + 0   , 0 );//第一列为0 
         ds_fuzhi( *( * * p_p_sjb + i ) + 1   , 1 );//第二列先赋值为1
         for( j = 0 ; j < N ; j ++ ){               //求N次幂 
            ds_chengyi( *( * * p_p_sjb + i ) + 1   , JINZHI - 1 - i );
         } 
         for( j = 2 ; j <= WEISHU ; j ++ ){
            (*( * * p_p_sjb + i ))[j] = (*( * * p_p_sjb + i ))[j-1] ;
            ds_jiaru ( *( * * p_p_sjb + i ) + j , *( * * p_p_sjb + i ) + 1 ) ;
         }
      } 
   } 
} 

extern void qiongju( void )
{
  SHUJUBIAO *p_sjb = NULL ;

  jianli_sjb ( & p_sjb ); //建立数据表 
  xunhuan( WEISHU , JINZHI-1 , *p_sjb ) ;
  free ( p_sjb );

}

static void xunhuan( const int gssx /*个数上限*/, 
                     const int sz /*关于哪个数字*/, 
                     DASHU (*p_hang)[WEISHU + 1] /*指向一行数据*/)  
{
   static DASHU he  = { { 0 } }   ;//static DASHU he    ; // =0   待完成 
   DASHU        he_ = he ;        //记录累加前的值     
   static SHUZI_GESHU sz_gs ;
   
   if( sz > 0 ){
      int i;
      for( i = 0 ; i <= gssx ; i++ ){
         sz_gs[sz] = i ;          //记录数字的个数 
         ds_jiaru ( &he , *p_hang + i ) ; 
         xunhuan( gssx - i , sz - 1 , p_hang + 1 );
         he = he_ ;                  //恢复原来的值 
      }
   }
   else{
      sz_gs[sz] = gssx ;          //记录数字的个数 

      if( wenhe ( & sz_gs , &he ) == SHI ){ //验算两者是否"吻合" 
         jilu( & he );   //<=>记录结果
      }
   }
}

   考虑在另一个模块完成这个函数,为此在工程中添加"4_结果.h"。
   在"2_穷举.h" 中 // void jilu( DASHU * ); 之前加上 #include "4_结果.h",并把 // void  jilu( DASHU * ); 复制到 "4_结果.h" 中,此后"2_穷举.h"变为

/*2_穷举.h*/

#ifndef QIONGJU_H
#define QIONGJU_H 

              
/**************************类型定义**************************/ 
   #include "3_大数.h" 
   #include "常用.h"

/**************************函数原型**************************/ 
   
   extern void qiongju( void );
   #include <stdlib.h>                 //malloc()
   #include <string.h>                 //memcmp()
   #include "4_结果.h"                 //void jilu(DASHU * );
     
#endif // QIONGJU_H

   在 "4_结果.h" 中将 void jilu(DASHU * ); 改写为
   extern void jilu(DASHU * );
   并在其前面添加 #include "3_大数.h" 预处理命令。此时"4_结果.h"的内容为

/*4_结果.h*/

#ifndef JIEGUO_H
#define JIEGUO_H 

              
/**************************类型定义**************************/ 
   #include "3_大数.h"    
/**************************函数原型**************************/ 
   
   extern void jilu( DASHU * ); 
     
#endif // JIEGUO_H

   在工程中添加"4_结果.c",在"4_结果.c"定义extern void jilu( DASHU * );

/*4_结果.c*/
#include "4_结果.h"

extern void jilu( DASHU *p_ds )
{
   
}

由于链表很容易实现把数据依照顺序排列,所以采用链表存储已经求出的花朵数。首先定义节点的数据类型

/*4_结果.h*/

#ifndef JIEGUO_H
#define JIEGUO_H 

              
/**************************类型定义**************************/ 
   #include "3_大数.h"    
   typedef struct jd {
                      DASHU hds;          //花朵数 
                      struct jd *xiayige; //下一个          
                     }
                     JIEDIAN;
/**************************函数原型**************************/ 
   
   extern void jilu( DASHU * ); 
     
#endif // JIEGUO_H

  定义“头”的位置:由于main()中有函数需要使用,且用函数返回值的办法传回过于繁琐也很不自然,所以这里使用外部变量。但将其作用范围限制在仅仅模块内能使用(static)。下面是加入了一个节点的代码及测试代码

/*4_结果.c*/
#include "4_结果.h"

static JIEDIAN *tou = NULL ;//头 //在4_结果.h中加入 #include <stdlib.h> 
 
extern void jilu( DASHU *p_ds )
{
   JIEDIAN **p_t = &tou ;
   JIEDIAN *p_jd = NULL ;
   
   if((p_jd=malloc( sizeof (JIEDIAN ) ))==NULL ){  // 添加节点 
      printf("无法存储");
      exit(1);
   }
   else{
      p_jd->hds = *p_ds         ;                  //写入节点 
   }
   
   while ( *p_t != NULL 
   /* || (*p_t)->hds 小于 *p_ds */ ) {
      p_t = &(*p_t)->xyg ;
   }

   //加入到链表中 
   p_jd -> xyg = * p_t ;
   * p_t = p_jd ;
   
   #ifdef CESHI
      ds_shuchu( &tou->hds );
      system("PAUSE");
      exit(2);
   #endif     
}

  测试输出153,测试通过。
  其中还有一个判断一大数是否小于另一大数的函数尚未完成,依照下面次序完成:
  在本地写函数调用—>在本地写函数原型—>将函数原型移动到"4_结果.h"
此时"4_结果.c"为

/*4_结果.c*/
#include "4_结果.h"

static JIEDIAN *tou = NULL ;//头 //在4_结果.h中加入 #include <stdlib.h> 

extern void jilu( DASHU *p_ds )
{
   JIEDIAN **p_t = &tou ;
   JIEDIAN *p_jd = NULL ;
   
   if((p_jd = malloc( sizeof (JIEDIAN ) ))==NULL ){  // 添加节点 
      printf("无法存储");
      exit(1);
   }
   else{
      p_jd->hds = *p_ds         ;                  //写入节点 
   }
   
   while ( *p_t != NULL 
        || ( xiaoyu(&(*p_t)->hds , p_ds ) == SHI ) // #include "常用.h" 
   /* || (*p_t)->hds 小于 *p_ds */ ) {
      p_t = &(*p_t)->xyg ;
   }

   //加入到链表中 
   p_jd -> xyg = * p_t ;
   * p_t = p_jd ;
   
   #ifdef CESHI
      ds_shuchu( &tou->hds );
      system("PAUSE");
      //exit(2);
   #endif     
}


->在"4_结果.h"中加上

#include "3_大数.h"

之后将函数原型移动到"3_大数.h"

/*4_结果.h*/

#ifndef JIEGUO_H
#define JIEGUO_H 

              
/**************************类型定义**************************/ 
   #include "3_大数.h"    
   typedef struct jd {
                      DASHU hds;          //花朵数 
                      struct jd *xyg; //下一个          
                     }
                     JIEDIAN;
   #include "常用.h"                     
/**************************函数原型**************************/ 
   
   extern void jilu( DASHU * ); 
   #include "3_大数.h"          //xiaoyu()
   #include <stdlib.h>          //malloc(),NULL  
#endif // JIEGUO_H
/*3_大数.h*/

#ifndef DASHU_H
#define DASHU_H 

#include "0_问题.h"             //DASHU用到了WEISHU 

/**************************类型定义**************************/ 
//gw_sz[0]为个位,gw_sz[WEISHU-1]为最高位
//gw_sz[WEISHU-1]的值大于等于JINZHI表示溢出
   typedef struct { 
                   int gw_sz[WEISHU] ; 
                  }  
                  DASHU ;          
   #include "常用.h"
   
/**************************函数原型**************************/ 
   
   extern void ds_fuzhi ( DASHU * const , const int ) ;  
   extern void ds_shuchu( const  DASHU * const ) ;    
   extern void ds_jiaru ( DASHU * const ,  const DASHU * const  ) ;
   extern void ds_chengyi( DASHU * const , const int );     
   extern SF chaoguo_W(const DASHU * const);
   extern SF buzu_W(const DASHU * const);
   extern void qiu_sz_gs( int (*)[JINZHI] , const DASHU * const ) ;
   extern SF xiaoyu ( const DASHU * const, const DASHU * const) ;      
#endif // DASHU_H

->在"3_大数.c"中给出函数定义:

extern SF xiaoyu ( const DASHU * const p_ds1, const DASHU * const p_ds2) 
{
   int *t1 =  p_ds1-> gw_sz , * w1 = t1 + WEISHU -1 ; 
   int *t2 =  p_ds2-> gw_sz , * w2 = t2 + WEISHU -1 ; 
   while( w1 > t1 ){
      if( *w1 < * w2){
         return SHI ;
      }
      if( *w1-- > * w2-- ){
         return FOU ;
      }
   }
   if(*w1<*w2){
      return SHI ;
   }
   return FOU ;
}

之后在main()中组织测试

#ifdef CESHI               //测试

   int main( void )
   {
      #define TEST_xiaoyu
      #ifdef  TEST_xiaoyu
      #include "3_大数.h"
       {
         DASHU t1,t2 ;
         ds_fuzhi(&t1,234);
         ds_fuzhi(&t2,567);
         
         printf("%d\n",xiaoyu(&t1,&t2)==SHI);            
       } 
      #endif

      //……前面进行的其他测试(略)

      system("PAUSE"); 
      return 0;
   }

#endif //CESHI

  测试通过。至此,由qiongju()函数引出的全部函数完成。

22.输出结果  

  回到main()完成“//输出”部分
  shuchu();//extern void shuchu(void);
  依照下面次序
  在本地写出函数调用—>在本地写函数原型—>将函数原型移动到"1_MAIN.h"

#ifdef QIUJIE              //求解

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

->在"1_MAIN.h"中加上

#include "4_结果.h"

,之后将函数原型移动到"4_结果.h"

/*1_MAIN.h*/
#ifndef MAIN_H
#define MAIN_H 

             
/**************************类型定义**************************/ 


/**************************函数原型**************************/ 

   #include <stdlib.h>                 //system()
   #include "2_穷举.h"                 //qiongju()
   #include "4_结果.h"     
#endif // MAIN_H


 
/*4_结果.h*/

#ifndef JIEGUO_H
#define JIEGUO_H 

              
/**************************类型定义**************************/ 
   #include "3_大数.h"    
   typedef struct jd {
                      DASHU hds;          //花朵数 
                      struct jd *xyg; //下一个          
                     }
                     JIEDIAN;
   #include "常用.h"                     
/**************************函数原型**************************/ 
   
   extern void jilu( DASHU * ); 
   #include "3_大数.h"       
   #include <stdlib.h>          //malloc(),NULL  
   extern void shuchu(void);   
#endif // JIEGUO_H

->在"4_结果.c"中给出函数定义

extern void shuchu(void)
{
   
   while(tou!=NULL){
      JIEDIAN *p_xyg = tou-> xyg ;
      ds_shuchu(&tou->hds);
      free( tou );
      tou = p_xyg ;   
   }
   tou = NULL ;
} 

  本以为一切都写完了,直接把"0_问题.h"中的

  #define CESHI 改成了 #define QIUJIE
  兴高采烈地编译运行,结果……发生了可怕的错误。
  后经过仔细检查,发现错误出在extern void jilu( DASHU *p_ds )中
   while ( *p_t != NULL 
          || ( xiaoyu(&(*p_t)->hds , p_ds ) == SHI )
  实际上却应为
   while ( *p_t != NULL 
          && ( xiaoyu(&(*p_t)->hds , p_ds ) == SHI )

  教训就是,前面对这个函数测试的不充分。在完成xiaoyu()函数前,测试了加入一个节点的情形,完成xiaoyu()函数之后,本应再测试一次  jilu()函数,但由于完成在即,心存侥幸地偷懒了。
  修正这个BUG之后,编译运行,程序的运行结果为
  128468643043731391252
  449177399146038697307
  运行时间约10秒。


  

转载于:https://www.cnblogs.com/KBTiller/archive/2011/06/08/2075597.html

相关文章:

  • NHibernate 学习第三天 Web.config 的配置
  • 使用BIOS进行键盘输入和磁盘读写03 - 零基础入门学习汇编语言77(完)
  • MFC中的窗口绘图问题
  • 【转载】Linux下进程的建立
  • SQL SERVER2005几个性能优化综述
  • windows phone7 mango 多人在线游戏
  • ISAG短信上下行的纠结
  • ASP.NET MVC3书店--第三节 视图与视图模型(转)
  • ASP.NET Session丢失问题原因及解决方案
  • SetWaitableTimer 通过异步程序调用(APC)实现的定时功能
  • C#扩展和收缩代码
  • Activity的taskAffinity属性
  • C# Winform利用POST传值方式模拟表单提交数据(Winform与网页交互)
  • Oracle Namespace 说明
  • linux目录配置 FHS
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • Android 架构优化~MVP 架构改造
  • android图片蒙层
  • AWS实战 - 利用IAM对S3做访问控制
  • Js基础知识(四) - js运行原理与机制
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • React-生命周期杂记
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 关于Java中分层中遇到的一些问题
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 基于webpack 的 vue 多页架构
  • 简单易用的leetcode开发测试工具(npm)
  • 将回调地狱按在地上摩擦的Promise
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 前端_面试
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 使用权重正则化较少模型过拟合
  • 学习笔记:对象,原型和继承(1)
  • 由插件封装引出的一丢丢思考
  • 自动记录MySQL慢查询快照脚本
  • #Z0458. 树的中心2
  • $L^p$ 调和函数恒为零
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (day 12)JavaScript学习笔记(数组3)
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (LeetCode) T14. Longest Common Prefix
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (利用IDEA+Maven)定制属于自己的jar包
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)ORM
  • (转)为C# Windows服务添加安装程序
  • (转)重识new
  • .Net 高效开发之不可错过的实用工具
  • .ui文件相关
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • @Valid和@NotNull字段校验使用
  • [ Linux ] Linux信号概述 信号的产生
  • [1159]adb判断手机屏幕状态并点亮屏幕
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]