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

本文详细介绍了如何实现大数运算中的赋值与加法操作,并通过具体代码示例展示了如何逐步修改和完善相关函数,以支持求解特定数学问题。

本文前一部分的链接
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


修改

ContractedBlock.gif ExpandedBlockStart.gif 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()函数(求各位数字的一次方之和),通过。

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

转载于:https://www.cnblogs.com/KBTiller/archive/2011/06/03/2072122.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值