zoukankan      html  css  js  c++  java
  • 代码意识流——花朵数问题(七)

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

    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(
    '\n');
    }
    #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)^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 ){ //验算两者是否"吻合"
    #ifdef CESHI
    ds_shuchu (
    & he );
    puts(
    "吻合");
    #endif
    //<=>记录结果
    }
    }
    }

    "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 ;
    #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 ) ;

    #endif // DASHU_H

    “3_大数.c”演变为

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

    static void ds_jinwei ( DASHU * const );

    //统计*p_he中的各数字个数=> *p_sz_gs
    extern void qiu_sz_gs( int (*p_sz_gs)[JINZHI] , const DASHU * const p_he )
    {
    int * t = p_he->gw_sz ;
    while( t < p_he->gw_sz + WEISHU ){
    (
    *p_sz_gs)[*t++] ++ ;
    }

    }

    extern SF buzu_W(const DASHU * const p_ds)
    {
    if(p_ds->gw_sz[WEISHU-1] == 0 ){
    return SHI ;
    }
    return FOU ;
    }
    //判断是否超过WEISHU
    extern SF chaoguo_W(const DASHU * const p_ds)
    {
    if(p_ds->gw_sz[WEISHU-1] >=JINZHI ){
    return SHI ;
    }
    return FOU ;
    }

    //* p_ds *= cs
    extern void ds_chengyi( DASHU * const p_ds , const int cs )
    {
    int * t = p_ds->gw_sz ;
    while( t < p_ds->gw_sz + WEISHU ){
    *t++ *=cs ;
    }
    ds_jinwei ( p_ds );
    }

    //进位
    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 ;
    }
    }
    }

    编译运行,结果为
    153
    吻合
    370
    吻合
    371
    吻合
    407
    吻合

    总算看到点亮了。

  • 相关阅读:
    一些有用的正则
    UNION ALL合表查询
    远程桌面连接:出现身份验证错误,要求的函数不受支持,可能是由于CredSSP加密Oracle修正的解决方法
    Ubuntu20.04安装、配置openvas
    awvs13破解安装、批量扫描脚本
    剑指05题
    时间复杂度o(1), o(n), o(logn), o(nlogn)
    Intellij IDEA 注释模板
    Explain详解
    Hibernate中get()和load()的区别
  • 原文地址:https://www.cnblogs.com/KBTiller/p/2074344.html
Copyright © 2011-2022 走看看