代码意识流——花朵数问题(七)
20.验算
验算过程的基本思路是求出“和”中各个数字有多少个,然后与得到这个"和"的数字组合比较,如果两者一致则“和”是一个花朵数。
例如,由一个5、一个3和一个1可以得到这三个数字的3次方的和为5^3+3^3+1^3==153,而153恰好是由一个5、一个3和一个1这三个数字构成这时就可以断定153是花朵数。
反之,由一个5、一个3和一个2可以得到这三个数字的3次方的和为,5^3+3^3+2^3==160,160中有一个6、一个1和一个0,与求得160的三个数字的组合(5,3,2)不符,这就表明160不是花朵数。
这种算法首先要记录求出数字N次方之和的各个数字的个数。
记录各数字的个数在"2_穷举.c"定义这种数据类型
typedef unsigned int SHUZI_GESHU[JINZHI];
//SHUZI_GESHU[d]存储数字d的个数在xunhuan()中定义这种类型的局部变量,显然这应该是static类别的
static SHUZI_GESHU sz_gs ;
记录递归过程中各个数字的个数,并测试
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 ; //记录数字的个数 #ifdef CESHI { int i; for ( i = 0 ; i < JINZHI ; i++ ){ printf("%d*%d " , sz_gs[i] , i ); } putchar( ); } #endif //验算<=>记录结果 }}测试通过。
接着在xunhuan()中写出验算的代码,判断“和”中数字出现的次数与sz_gs 中的记录是否一致xunhuan()
{
……
if( 吻合 ( & sz_gs , &he ) == 是 ){ //验算
//<=>记录结果
}}
吻合 ( & sz_gs , &和 )
{
int 和中各数字的个数[JINZHI];if( 超过W位(和) == 是 || 不足W位(和) == 是 ){ //#include "3_大数.h"
return 否;
}求和中各数字的个数( &和中各数字的个数 , &和 );//#include "3_大数.h"
if ( memcmp (和中各数字的个数 ,sz_gs ,sizeof 和中各数字的个数 )==0 ){ //#include <string.h>
return 是;
}
return 否;
}这段代码涉及到很多回答是或否的问题,由于讨厌在写代码时费神用0或1思考这样的问题,在工程中加入了这样一个文件
/*常用.h*/ #ifndef CHANGYONG_H#define CHANGYONG_H typedef enum { SHI , FOU } SF ; #endif // CHANGYONG_H并分别在"2_穷举.h"、"3_大数.h"中添加了
#include "常用.h"现在,“2_穷举.h”演变成
/*2_穷举.h*/#ifndef QIONGJU_H#define QIONGJU_H /**************************类型定义**************************/ #include "3_大数.h" #include "常用.h"/**************************函数原型**************************/ extern void qiongju( void ); #include <stdlib.h> //malloc() #endif // QIONGJU_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)^Nstatic 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 );}sta
补充:软件开发 , C语言 ,