前文链接:帮初学者改代码——playerc之“练习:求完数问题”(上)

  再来看看be_ferfect()应该如何改。

  be_ferfect()函数的功能是判断number是否为完数,同时把因子对写入divisers数组。以28这个完数为例,在数组中将依次写入

  1 28 2 14 4 7

  输出时则按要求依大小次序输出 1 2 4 7 14。先从前跳到后,到头之后掉头,再从后跳到前。

  这种写入的方式决定了输出代码写起来要困难一些。如果希望输出写得容易些的话,写入时就必须改变这种图省事的办法。

  有很多种方案可选:

  第一种方案,从小到大写

   int divisers_count = 1 ;
for ( i = 2 ; i < number ; ++ i ){
if (!( number % i)){ divisers[divisers_count ++ ] = i;
sum += i; if ( sum > number )
return false;
}
}

  这显然简洁多了。作者没有考虑这种方法应该是有自己的想法,估计是认为一对儿一对儿的写更快些。对比一下

   int divisers_count = 2 ;

   for ( i = 2 , i_max = sqrt(number)+1 ; i < i_max ; ++ i ){
if (!(number % i)){ divisers[divisers_count ++ ] = i;
sum += i; diviser = number / i ;
if ( diviser != i ) {
divisers[ divisers_count ++ ] = diviser;
sum += diviser;
} if ( sum > number )
return false;
}
}

  作者的写法做了大约2√n次除法、求余和不等于运算,而第一种方案要做n-1次除法。作者的写法虽然复杂,但优势还是有一些的。

  第二种方案,用两个数组存储因子

  1   2   4

  28 14 7

  这样即保留了作者算法的优势,输出的代码也比较容易写。但这要整个地修改代码的基本数据结构,改动比较大。所以这里就不用了。

  第三种方案,从数组两头向中间存储

  1 2 4 0 0 0 …… 7 14

  这种方案,虽然看起来有点别扭,但读写数组都更容易些,也不需要改动数据结构,权衡之下,是唯一较为可取的方案。

  采用这种方案的代码如下:

#include <stdio.h>
#include <stdbool.h> bool be_ferfect( int , int * , int * );
void output( int [] , int ); #define TOP (10000)
#define DIVISERS_MAX_LENGTH ((3+1)*(1+1)*(1+1)*(1+1)*(1+1)) int main( void )
{
int number; for( number = 2 ; number < ( TOP + 1 ) ; ++number ){ int divisers[DIVISERS_MAX_LENGTH] = { 1 } ; if ( be_ferfect( number , divisers ,
divisers + DIVISERS_MAX_LENGTH - 1 ) ){
printf("%d ,Its factors are : ", number) ;
output ( divisers , DIVISERS_MAX_LENGTH ) ;
}
} return 0;
} bool be_ferfect( int number , int * p_b , int * p_e )
{
int i ;
int sum = * p_b ++ ; for ( i = 2 ; i * i < number ; ++ i ){
if ( number % i != 0 )
continue ; sum += ( * p_b ++ = i ) + ( * p_e -- = number / i ) ; if ( sum > number )
return false;
} if ( i * i == number )
sum += ( * p_b ++ = i) ; return sum == number ;
} void output ( int divisers[] , int size )
{
int i ; for ( i = 0 ; i < size ; i ++ ){ if ( divisers[i] == 0 )
continue ; printf ("%d ",divisers[i]);
}
putchar('\n');
}

(完)

帮初学者改代码——playerc之“练习:求完数问题”(下)的更多相关文章

  1. 帮初学者改代码——playerc之“练习:求完数问题”(上)

    原文:“练习:求完数问题” 原代码: // #include <stdio.h> #include <stdlib.h> #include <math.h> #de ...

  2. 帮初学者改代码——有多少青春可以挥霍之“c语言 多重排序”

    原文:“c语言 多重排序” 原代码: #include<stdio.h> #include<string.h> struct A { char name[100]; int g ...

  3. 蓝桥杯 算法训练 ALGO-152 8-2求完数

     算法训练 8-2求完数   时间限制:50.0s   内存限制:256.0MB 问题描述 如果一个自然数的所有小于自身的因子之和等于该数,则称为完数.设计算法,打印1-9999之间的所有完数. 样例 ...

  4. openmp 并行求完数

    // GetWanShu.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "omp.h" #inclu ...

  5. Java50道经典习题-程序9 求完数

    题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程找出1000以内的所有完数. public class Prog9 { public stati ...

  6. JAVA 基础编程练习题9 【程序 9 求完数】

    9 [程序 9 求完数] 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如 6=1+2+3.编程找出 1000 以内的 所有完数. package cskaoyan ...

  7. Java实现 蓝桥杯VIP 算法训练 求完数

    问题描述 如果一个自然数的所有小于自身的因子之和等于该数,则称为完数.设计算法,打印1-9999之间的所有完数. 样例输出 与上面的样例输入对应的输出. 例: 数据规模和约定 1-9999 publi ...

  8. ALGO-152_蓝桥杯_算法训练_8-2求完数

    记: 掌握完数的概念 AC代码: #include <stdio.h> int main(void) { int i,j,sum; ; i <= ; i ++) { sum = ; ...

  9. OpenMP求完数

    源代码: #include "stdafx.h" //必须写在首行,因为其前面的include都会被忽略 #include "omp.h" #include & ...

随机推荐

  1. 长城坑爹宽带,劫持用户DNS赚取购物返利

    今天回来登录www.jd.com 打算淘点东西,登录后发现地址栏跳到 http://www.jd.com/?utm_source=click.linktech.cn&utm_medium=tu ...

  2. Spark Programming--WordCount

    首先在$SPARK_HOME主目录下建立一个test文件夹,里面放一些文件(注意文件全部内容都可被hadoop用户访问,否则运行会出现permission denied的错误) 打开pyspark: ...

  3. JavaScript学习之对象

    JavaScript对象 一.对象简介 JavaScript 是面向对象的编程语言 (OOP).OOP 语言使我们有能力定义自己的对象和变量类型.注意:对象只是一种特殊的数据.对象拥有属性和方法. 1 ...

  4. Excel导入数据到Sql server 中出错:“文本被截断,或者一个或多个字符在目标代码页中没有匹配项”

    从Excel导入数据到Sql server 时,由于表中的数据有的很长,导入时出现如下错误(如果数据不是很长,255内以内,则不会出现错误): 出错原因: SQL Server的导入导出为了确定数据表 ...

  5. Android 退出app,后台推送的服务也停止了,怎么可以做到不停止后台服务呢?

    service粘性等的那4种方式试了,三星的可以,小米老款手机可以,新款不行,华为新款也不行,还有魅族什么的,都不行,新款的手机上都有一个安全中心,只有在安全中心里面添加上允许app自启动才可以 怎么 ...

  6. 源码维护基本命令diff_patch

    源码维护基本命令 diff------生成源代码补丁diff [命令行选项] 源文件 新文件-r 递归处理相应目录-N 包含新文件到patch-u 输出统一格式(unified format),这种格 ...

  7. Java IO之一读取文件

    package com.lf.iopreoject; import java.io.BufferedReader; import java.io.File; import java.io.FileIn ...

  8. 使用dbms_system追踪其它session

    dbms_system是内部包,建议在官方指导下使用该包. SQL> desc dbms_system PROCEDURE ADD_PARAMETER_VALUE Argument Name T ...

  9. Java基础之处理事件——添加工具提示(Sketcher 9 with tooltips)

    控制台程序. 在Java中实现对工具提示的支持是非常简单的,秘诀仍在我们一直使用的Action对象中.Action对象拥有存储工具提示文本的内置功能因为文本是通过SHORT_DESCRIPTION键提 ...

  10. ForkJoin框架

    1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过 ...