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

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

15.改写代码(续)

  //待修改 he += i * sz  ;
  这句实际上是测试用的代码。问题在这里提出的要求是把某个数字的N次方加到he中,而某个数字的N次方可能是一个很大的数字,因此需要用DASHU类型来表示。也就是说对于问题,这里提出的要求是  DASHU += DASHU
  为了能够测试且写出问题所实际需要的函数,这里把
  he += i * sz  ;
  分为两步
   { 
     DASHU temp ;
     temp =  i * sz ;
     he   += temp ; 
    }
  这里要求两个运算“=”、“+=”,由于运算对象是自己创建的新的数据类型,C语言并没有定义这种新数据类型的“=”、“+=”运算,所以只能自己通过定义函数的办法自行定义。
  将 temp =  i * sz ; 改为 ds_fuzhi ( &temp , i * sz ) ;
  (使用指针的缘故是因为temp被函数改变,这和scanf()里使用&运算的道理一样)
  同时可给出函数原型
  void ds_fuzhi ( DASHU * const , const int ) ;

修改(2_穷举.c  xunhuan()函数 )

static void xunhuan( const int gssx /*个数上限*/,
const int sz /*关于哪个数字*/)
{
static DASHU he = { { 0 } } ;//static DASHU he ; // =0 待完成
DASHU he_ = he ; //记录累加前的值

if( sz > 0 ){
int i;
for( i = 0 ; i <= gssx ; i++ ){
printf(
"%d*%d +" , i , sz );
{
DASHU temp ;
ds_fuzhi (
&temp , i * sz ) ; //void ds_fuzhi ( DASHU * const , const int ) ;
//he += temp ; // 每次调用都从he开始累加
}

xunhuan( gssx
- i , sz - 1 );
he
= he_ ; //恢复原来的值
}
}
else{
//待修改 he += gssx * sz ;
//待修改 printf("%d*%d = %d" , gssx , sz , he );
putchar('\n');//<=>验算<=>记录结果
}
}


  因为在前面已经 #include "3_大数.h"
  所以直接把函数原型 ds_fuzhi ( DASHU * const , const int ) ; 移动到"3_大数.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 ;

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

extern void ds_fuzhi ( DASHU * const , const int ) ;
#endif // DASHU_H

  在工程中添加
"3_大数.c" 源文件,并写出ds_fuzhi()函数定义

/*3_大数.c*/
#include
"3_大数.h"

//在*p_ds中写入n
extern void ds_fuzhi ( DASHU * const p_ds , const int n )
{
p_ds
->gw_sz[0] = n ;

//可能有进位,同时把高位写为0
{
int *t = p_ds->gw_sz , //指向 p_ds->gw_sz[0]
*w = t + WEISHU - 1 ; //指向 p_ds->gw_sz[WEISHU-1]
while( t < w ){
*( t + 1 ) = * t / JINZHI ;
* t ++ %= JINZHI ;
}
}
}

  编译,通过。之后首先考虑测试
  由于在xunhuan()函数里面写测试语句可能把代码弄得很乱,所以这次在main()中写测试代码

  修改main()为:

#ifdef CESHI //测试

int main( void )
{
#define TEST_ds_fuzhi

#ifdef TEST_ds_fuzhi
{
#include
"3_大数.h"
DASHU t ;
ds_fuzhi(
&t,12);
{
int i ;
for(i=WEISHU-1;i>=0;i--){
printf(
"%d",t.gw_sz[i]);
}
putchar(
'\n');
}
}
#endif

#ifdef TEST_qiongju
qiongju();
//保留,以后继续测试
#endif

system(
"PAUSE");
return 0;
}

#endif //CESHI


输出:012。测试通过


  回到xunhuan()函数继续未完成的修改。(要点:先写出ds_jiaru() 、ds_shuchu()的函数调用及原型)

static void xunhuan( const int gssx /*个数上限*/,
const int sz /*关于哪个数字*/)
{
static DASHU he = { { 0 } } ;//static DASHU he ; // =0 待完成
DASHU he_ = he ; //记录累加前的值 //记录累加前的值

if( sz > 0 ){
int i;
for( i = 0 ; i <= gssx ; i++ ){
printf(
"%d*%d +" , i , sz );
{
DASHU temp ;
ds_fuzhi (
&temp , i * sz ) ;
ds_jiaru (
&he , &temp ) ;
//void ds_jiaru ( DASHU * const , const DASHU * const ) ; // 每次调用都从he开始累加
}
xunhuan( gssx
- i , sz - 1 );
he
= he_ ; //恢复原来的值
}
}
else{
{
DASHU temp ;
ds_fuzhi (
&temp , gssx * sz ) ;
ds_jiaru (
&he , &temp ) ; //待修改 he += gssx * sz ;
}
//待修改 printf("%d*%d = %d" , gssx , sz , he );
printf("%d*%d = " , gssx , sz );
ds_shuchu(
&he ) ;//extern void ds_shuchu( const DASHU * const ) ;
//<=>验算<=>记录结果
}
}


  把ds_jiaru() 、ds_shuchu()的函数原型移动到 “3_大数.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 ;

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

extern void ds_fuzhi ( DASHU * const , const int ) ;
extern void ds_shuchu( const DASHU * const ) ;
extern void ds_jiaru ( DASHU * const , const DASHU * const ) ;
#endif //DASHU_H


修改

View Code
/*3_大数.c*/
#include
"3_大数.h"

static void ds_jinwei ( DASHU * const );

//进位
static void ds_jinwei ( DASHU * const p_ds )
{
int * t = p_ds->gw_sz , * const w = t + WEISHU - 1 ;
while( t < w ){
*( t + 1 ) += * t / JINZHI ;
* t ++ %= JINZHI ;
}
}

// *p_he += *p_js
extern void ds_jiaru ( DASHU * const p_he , const DASHU * const p_js )
{
int *he_t = p_he->gw_sz , * const he_w = he_t + WEISHU - 1 ;
const int *js_t = p_js->gw_sz ;
while( he_t < he_w ){
*he_t++ += *js_t++ ;
}
ds_jinwei ( p_he );
// static void ds_jinwei ( DASHU * const );
}

extern void ds_shuchu( const DASHU * const p_ds )
{
int * const t = p_ds->gw_sz , *w = t + WEISHU - 1 ;
while( w > t && *w == 0 ){ //高位0不输出
w--;
}
while( w > t ){
printf(
"%d" , * w -- );
}
printf(
"%d\n" , * t ) ;
}

//在*p_ds中写入n
extern void ds_fuzhi ( DASHU * const p_ds , const int n )
{
p_ds
->gw_sz[0] = n ;
//可能有进位,同时把高位写为0
{
int *t = p_ds->gw_sz , //指向 p_ds->gw_sz[0]
*w = t + WEISHU - 1 ; //指向 p_ds->gw_sz[WEISHU-1]
while( t < w ){
*( t + 1 ) = * t / JINZHI ;
* t ++ %= JINZHI ;
}
}
}


  期间对ds_shuchu(), ds_jiaru()进行了测试,均通过。

  最后,修改main(),重新测试qiongju()函数(求各位数字的一次方之和),通过。

  至此完成了数字组合和大数运算有关的主要函数。

posted @ 2011-06-03 17:50  键盘农夫  阅读(1387)  评论(4编辑  收藏  举报